クラスを使用するすべてのファイルにコード行を追加せずに、C#でクラス名のエイリアスを作成するにはどうすればよいですか?


87

クラス名のエイリアスを作成したい。次の構文は完璧です。

public class LongClassNameOrOneThatContainsVersionsOrDomainSpecificName
{
   ...
}

public class MyName = LongClassNameOrOneThatContainsVersionOrDomainSpecificName;

しかし、それはコンパイルされません。


この例は、便宜上提供されています。システム全体の設計を変更することを提案して、この特定の問題を解決しようとしないでください。この例の存在または欠如は、元の質問を変更しません。

一部の既存のコードは、静的クラスの存在に依存しています。

public static class ColorScheme
{
   ...
}

この配色は、Outlook2003の配色です。Outlook 2003の配色を維持しながら、Outlook2007の配色を導入したいと思います。

public static class Outlook2003ColorScheme
{
   ...
}

public static class Outlook2007ColorScheme
{
   ...
}

しかし、私はまだコードがと呼ばれる静的クラスの存在に依存しているという事実に直面していColorSchemeます。私の最初の考えは、次のColorSchemeいずれOutlook2003かから継承するクラスを作成することでしたOutlook2007

public static class ColorScheme : Outlook2007ColorScheme
{
}

ただし、静的クラスから継承することはできません。

私の次の考えは静的ColorSchemeクラスを作成することでしたが、makeOutlook2003ColorSchemeOutlook2007ColorSchemeclassesは非静的です。次に、静的ColorSchemeクラスの静的変数は、次のいずれかの「真の」配色を指すことができます。

public static class ColorScheme
{
    private static CustomColorScheme = new Outlook2007ColorScheme();
    ...
}

private class CustomColorScheme 
{ 
   ...
}

private class Outlook2008ColorScheme : CustomColorScheme 
{
    ...
}

private class Outlook2003ColorScheme : CustomColorScheme 
{
   ...
}

ただし、読み取り専用の静的Colorで構成されたクラスをオーバーライド可能なプロパティに変換する必要があります。次に、ColorSchemeクラスで30個の異なるプロパティゲッターを含まれているオブジェクトにサンクダウンする必要があります。

タイピングが多すぎます。

したがって、次の考えは、クラスのエイリアスを作成することでした。

public static ColorScheme = Outlook2007ColorScheme;

しかし、それはコンパイルされません。

静的クラスを別の名前にエイリアスするにはどうすればよいですか?


更新:誰かが「C#ではこれを行うことはできません」という回答を追加してください。それを承認済みの回答としてマークできます。同じ質問への回答が必要な他の人は、この質問、受け入れられた回答、および役立つ場合とそうでない場合があるいくつかの回避策を見つけるでしょう。

この質問を締めくくりたいと思います。


実装したくない場合でも、Chrisの回答を受け入れる方がよいでしょう
devio 2008

2
それは答えではなく、回避策です。答えは、少なくとも誰かがやって来て実際の構文を投稿するまではできないということです。
イアン・ボイド

1
私が取り組んでいるVS2010およびVS2017 c#プロジェクトでは、最高評価のコメントが問題なく機能するため、ここに来る人にとっては、受け入れられた答えは正しくありません。エイリアスを設定するときにクラスを指定するには、完全修飾名前空間を使用する必要がありますが、一度設定すると、エイリアスは定義されたスコープ内で機能します。
J-Americano

彼が何を求めているのかを理解する前に、私はイアンの答えと彼のコメントを非常に詳細に読まなければなりませんでした。彼は、クラスを参照するすべてのファイルの先頭に追加するのではなく、クラスエイリアスを1か所で宣言したいと考えています。これをサポートする強く型付けされた言語を私は知りません。(誰かがそのような言語を知っているなら、私はそれについて知りたいです。)私はこれをより明確にするためにタイトルを編集しました。
toolmakerSteve 2018

ところで、似たようなことをしようとしている人にとっては、これらが定義しているクラスである場合、C#アプローチはinterface、すべてのクラスが実装するを定義することです。chills42の回答で述べたように。次に、現在の状況(プラットフォーム/ OSなど)または構成ファイルに応じて、そのインターフェイスを実装するオブジェクトを返す「サービス」または「ファクトリ」を定義できます。
toolmakerSteve 2018

回答:


129

できません。次善の策は、クラスを使用するファイルに宣言を含めることですusing

たとえば、インポートエイリアスを使用して(準typedef代替として)依存コードを書き直すことができます。

using ColorScheme = The.Fully.Qualified.Namespace.Outlook2007ColorScheme;

残念ながら、これは名前を使用するすべてのスコープ/ファイルに入る必要があります。

したがって、これがあなたの場合に実用的かどうかはわかりません。


9
元のクラスを含むファイルの先頭に配置できれば、それは素晴らしいことです。ただし、usingすべての壊れたコードにに追加する必要があります。また、値が単一のエイリアスを持っていることを否定します。これにより、既存のColorSchemeクラスのすべてのユーザーを、変更せずに新しいクラスを使用するように切り替えることができます。言い換えれば、ColorSchemeクラスを別のクラスにエイリアスしたいのです。
イアンボイド2011年

同じことを達成し、継承を使用してエイリアスを伝播する方法はありますか?つまり、MyClassを拡張するすべてのクラスは、MyClassソースファイルにusingステートメントを追加するだけで、.Fully.Qualified ... ColorSchemeの代わりにColorSchemeを使用できますか?
FlorianBurel19年

まあ、それは私の場合には非常に実用的でした。最後に、C#はファイルパスの描画を停止します。
ElDoRado1239

25

次のコード行を追加することで、クラスのエイリアスを作成できます。

using Outlook2007ColorScheme = YourNameSpace.ColorScheme;

「ColorScheme」という名前は現在のコンテキストには存在しません
Ian Boyd

7
Fully.Qualified.Namespace.Of.ColorScheme
Jamie Pate

C#では、この方法では名前空間(クラスではなく)のみをエイリアスできると思いましたが、VB.Netでは、を使用して名前空間またはクラスをエイリアスできますImports。私が間違っている?
ニック

using名前空間内にディレクティブを配置する場合、たとえば独自のクラスのエイリアスが必要な場合は、完全修飾名は必要ありません。
Elvedin Hamzagic 2016

12

あなたは(要件に応じてファクトリ|シングルトン)が必要です。前提は、クライアントコードが取得している配色を知る必要がないようにすることです。配色をアプリケーション全体に適用する必要がある場合は、シングルトンで十分です。さまざまな状況でさまざまなスキームを使用する可能性がある場合は、ファクトリパターンがおそらく最適な方法です。いずれにせよ、配色を変更する必要がある場合は、コードを1か所で変更するだけで済みます。

public interface ColorScheme {
    Color TitleBar { get; }
    Color Background{ get; }
    ...
}

public static class ColorSchemeFactory {

    private static ColorScheme scheme = new Outlook2007ColorScheme();

    public static ColorScheme GetColorScheme() { //Add applicable arguments
        return scheme;
    }
}

public class Outlook2003ColorScheme: ColorScheme {
   public Color TitleBar {
       get { return Color.LightBlue; }
   }

    public Color Background {
        get { return Color.Gray; }
    }
}

public class Outlook2007ColorScheme: ColorScheme {
   public Color TitleBar {
       get { return Color.Blue; }
   }

    public Color Background {
        get { return Color.White; }
    }
}

これは、ファクトリではなく、シングルトンパターンでの弱い試みのように見えます。ファクトリは、作成方法をパラメータ化する可能性が高くなります。次のようなものになります。publicstaticColorSchemeGetColorScheme(文字列記述子);
OwenP 2008年

本当-基本的な考え方は、office 2012がリリースされたときに、コードを1か所で変更するだけでよいことを確認することです。
Chris Marasti-Georg

1
これは間違いなく機能しますが、単純な問題に対する企業向けのソリューションであることは確かです。
イアン・ボイド

11

C#でクラス名をエイリアスすることはできません。

C#でクラス名をエイリアスしないでできることがあります。

ただし、元の質問に答えるには、C#でクラス名をエイリアスすることはできません。


更新:人々はなぜusing機能しないのか混乱しています。例:

Form1.cs

private void button1_Click(object sender, EventArgs e)
{
   this.BackColor = ColorScheme.ApplyColorScheme(this.BackColor);
}

ColorScheme.cs

class ColorScheme
{
    public static Color ApplyColorScheme(Color c) { ... }
}

そして、すべてが機能します。今、私は新しいクラスを作成し、そのエイリアス を作成したいと思いますColorSchemeコードを変更する必要がないように):

ColorScheme.cs

using ColorScheme = Outlook2007ColorScheme;

class Outlook2007ColorScheme
{
    public static Color ApplyColorScheme(Color c) { ... }
}

ああ、ごめんなさい。このコードはコンパイルされません:

ここに画像の説明を入力してください

私の質問は、C#でクラスをエイリアスする方法でした。それはできません。C#でクラス名をエイリアスしないでできることがあります。

  • 依存して変化するみんなColorSchemeusing ColorScheme代わりに(私は別名ができないため、コードの変更は回避)
  • ColorSchemeファクトリパターンを使用することに依存しているすべての人をポリモーフィッククラスまたはインターフェイスに変更します(エイリアスできないため、コード変更の回避策)

ただし、これらの回避策には、既存のコードの破壊が含まれます。オプションではありません。

人々がColorSchemeクラスの存在に依存している場合、私は実際にColorSchemeクラスをコピーして貼り付ける必要があります。

言い換えると、C#でクラス名をエイリアスすることはできません。

これは、エイリアスを定義できる他のオブジェクト指向言語とは対照的です。

ColorScheme = Outlook2007ColorScheme

そして、私は終わります。


21
あなたは絶対にC#でクラス名をエイリアスすることができます。"using <alias_name> = <fully_qualified_name>;"
clemahieu 2011

7
LIke @clemahieuによると、クラス名は絶対にエイリアスできます。完全修飾名を使用するだけです。さらに、ジェネリッククラスをエイリアシングする場合は、ジェネリッククラス修飾子を追加する必要があります。例:using ShortName = MyNamespace.SubNamespace.GenericClass <MyType>;
ダンモルフィス2011年

11
反対票-「C#でクラス名をエイリアスすることはできません」と述べました。あなたはできる。できないことは、クラス希望どおりにエイリアスすることです。これは非常に正当な要件ですが、ステートメントが正しくありません。
トムW

8
いくつかのポスターが指摘しているように、修飾名を使用しなければならないことは、エイリアシングを禁止するものではありません。クラスにエイリアスを付けることができます。これを行うには、完全修飾名を使用する必要があります。これは不便だと思うかもしれませんが、「C#でクラス名をエイリアスすることはできません」というステートメントは真になりません。おそらく、C#でエイリアシングが機能する方法は、期待していたものとは異なります。それは問題ありません-その場合は、それを述べてください。ただし、C#でクラス名をエイリアスすることはできます。これは、仕様では、提供されている定義に従って、そうすることができると規定されているためです。
トムW

5
私たちプログラマーが行間でステートメントを作成する方法が好きです。Ianが実際に言っているのは、C#は、誰もがやりたいと思っていて、できるはずの単純な基本的なことを実行できないため、ばかげて壊れているということです。彼は正しいです-特定のセマンティクスがあなたを幸せにするかどうか。
IQpierce 2013

10

これを試して:

using ColorScheme=[fully qualified].Outlook2007ColorScheme

「ColorScheme」という名前は現在のコンテキストには存在しません
Ian Boyd

2
Fully.Qualified.Namespace.Of.ColorScheme
Jamie Pate

6

OPが「回答」を受け入れてからずっと後にこれを見つけたユーザーのために、このコメントを追加します。C#でのエイリアスは、完全修飾名前空間を使用してクラス名を指定することで機能します。定義されたエイリアス名は、そのスコープ内で使用できます。例。

using aliasClass = Fully.Qualified.Namespace.Example;
//Example being the class in the Fully.Qualified.Namespace

public class Test{

  public void Test_Function(){

    aliasClass.DoStuff();
    //aliasClass here representing the Example class thus aliasing
    //aliasClass will be in scope for all code in my Test.cs file
  }

}

すばやく入力されたコードについてお詫びしますが、C#では実行できないとユーザーが誤解しないように、これを実装する方法を説明していることを願っています。


あなたが示した場合、これはより明確になります宣言、他のクラスのを: namespace Fully.Qualified.Namespace{ public class Example {... public void DoStuff(){... }... } }
toolmakerSteve 2018

1
明確にするために、これはイアンが求めているものとは異なります。Ianには、クラスを参照するソースファイルを変更できない(または変更したくない)状況があります。彼は、アプリケーションまたはライブラリの1つの場所だけに変更を加えて、他のすべてのコードが使用できる、目的の名前のクラスのように見える方法を望んでいます[その "using"ステートメントを複数のソースに追加する必要はありませんファイル-たとえば、そのソースを変更できない場合があります]。
toolmakerSteve 2018

4

希望する方法でエイリアスを作成しても、C#では機能しません。これは、エイリアシングがusingディレクティブを介して行われるためです。ディレクティブは、問題のファイル/名前空間に限定されています。古いクラス名を使用するファイルが50個ある場合、更新する場所は50個になります。

そうは言っても、コードの変更を可能な限り最小限に抑える簡単な解決策があると思います。を作るColorSchemeたクラスに実装して、実際のクラスへのあなたの通話用ファサードを、そして使用usingするかを決定するために、そのファイルにColorScheme使用します。

言い換えれば、これを行います:

using CurrentColorScheme = Outlook2007ColorScheme;
public static class ColorScheme
{
   public static Color ApplyColorScheme(Color c)
   {
       return CurrentColorScheme.ApplyColorScheme(c);
   }
   public static Something DoSomethingElse(Param a, Param b)
   {
       return CurrentColorScheme.DoSomethingElse(a, b);
   }
}

次に、コードビハインドで何も変更しません。

private void button1_Click(object sender, EventArgs e)
{
   this.BackColor = ColorScheme.ApplyColorScheme(this.BackColor);
}

その後、の値を更新できます ColorScheme 1行のコード(using CurrentColorScheme = Outlook2008ColorScheme;)を。

ここでいくつかの懸念があります:

  • 次に、すべての新しいメソッドまたはプロパティ定義を、ColorSchemeクラスとクラスの2か所に追加する必要があります。Outlook2007ColorScheme。これは余分な作業ですが、これが真のレガシーコードである場合は、頻繁に発生することはありません。ボーナスとして、のコードColorSchemeは非常に単純なので、起こりうるバグは非常に明白です。
  • この静的クラスの使用は、私には自然に思えません。私はおそらくこれを別の方法で行うためにレガシーコードをリファクタリングしようとしますが、あなたの状況ではそれが許されないかもしれないことも理解しています。
  • ColorScheme置き換えるクラスがすでにある場合は、このアプローチやその他のアプローチが問題になる可能性があります。そのクラスの名前をのような名前に変更してからColorSchemeOld、を介してアクセスすることをお勧めしますusing CurrentColorScheme = ColorSchemeOld;

3

何も追加しなくても、いつでも基本クラスから継承できると思います

public class Child : MyReallyReallyLongNamedClass {}

更新

ただし、classそれ自体をリファクタリングする機能がある場合:namespacesがないため、クラス名は通常、不必要に長くなります。

あなたのように例が表示された場合はApiLoginUserDataBaseUserWebPortalLoginUser、通常の欠如の指標であるnamespace名前の恐怖によるUserかもしれないが競合。

ただし、この場合、上記の投稿で指摘されているように、namespaceエイリアスを使用できます。

using LoginApi = MyCompany.Api.Login;
using AuthDB = MyCompany.DataBase.Auth;
using ViewModels = MyCompany.BananasPortal.Models;

// ...
AuthDB.User dbUser;
using ( var ctxt = new AuthDB.AuthContext() )
{
    dbUser = ctxt.Users.Find(userId);
}

var apiUser = new LoginApi.Models.User {
        Username = dbUser.EmailAddess,
        Password = "*****"
    };

LoginApi.UserSession apiUserSession = await LoginApi.Login(apiUser);
var vm = new ViewModels.User(apiUserSession.User.Details);
return View(vm);

class名前はすべてUserですが、namespacesが異なることに注意してください。PEP-20の引用:Pythonの禅

名前空間は素晴らしいアイデアの1つです。もっと多くのことをしましょう!

お役に立てれば


2
できない場合を除いて、常に:例:封印されたクラス
mikus 2016年

しかし、それは多くの場合うまくいきません。例:public class MyList:List {}-後でMyListを試す場合xyz = something.ToList(); あなたは立ち往生します。
オフラー2016年

@Offlerこのnewようなメソッドのキーワードを使用するか、独自のExtensionMethodsを考え出すこともできます(おそらくそうすべきです)。いずれにせよ、カスタムModels / ViewModels / POCOでは常にバニラコレクションクラス(つまり、Dictionary、List、IEnumerable、IQueryableなど)を使用する必要があるというのが私の強い意見です。Mvcが述べているように:
設定より規約

@percebusはすべての場合に機能するとは限りません。パーツがサポートされなくなったAPIを使用して新しいものに変換しようとしています。durign変換コードは他の人によって変更され、引き続き実行可能である必要があります。したがって、両方とも今すぐ使用できるはずです。700.000 LOC(コメントなし)を超えるものを変換し、それでも実行可能にすると、c ++スタイルのエイリアスが可能であれば、ファイル内の1つの場所だけで、エイリアスクラスをいずれかの実装に置き換えることができます。
オフラー2016年

RE-POST for EDIT @Offlerあなたが説明しているサウンドについては、インターフェースを備えたファクトリーのような何かが必要です。 IColorScheme oColorScheme = ColorSchemeFactory.Create(); また、依存性注入
percebus 2016年

2

インターフェイスの使用に変更することはできますか?

おそらくIColorScheme、すべてのクラスが実装するインターフェースを作成できますか?

これは、ChrisMarasti-Georgによって示されているファクトリパターンでうまく機能します。


可能性はありますが、使用する「現在の」配色であるクラスの名前を変更するのではなく、これ以上時間を費やすつもりはありません。
イアン・ボイド

0

これは非常に遅い部分的な答えですが、同じクラス「ColorScheme」を同じ名前空間「Outlook」で定義し、一方がOutlook2003ともう一方のOutlook2007と呼ばれる別々のアセンブリで定義する場合、必要なのは適切なアセンブリを参照することだけです。 。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.