クラスを使用するすべてのファイルにコード行を追加せずに、C#でクラス名をエイリアスするにはどうすればよいですか?
-
04-07-2019 - |
質問
iは、クラス名のエイリアスを作成します。次の構文が最適です:
public class LongClassNameOrOneThatContainsVersionsOrDomainSpecificName
{
...
}
public class MyName = LongClassNameOrOneThatContainsVersionOrDomainSpecificName;
しかし、コンパイルされません。
例
注この例は、便宜のためにのみ提供されています。システム全体の設計を変更することを提案して、この特定の問題を解決しようとしないでください。この例の有無は、元の質問を変更しません。
既存のコードの中には、静的クラスの存在に依存するものがあります:
public static class ColorScheme
{
...
}
この配色は、Outlook 2003の配色です。 Outlook 2003の配色を維持しながら、Outlook 2007の配色を導入したい:
public static class Outlook2003ColorScheme
{
...
}
public static class Outlook2007ColorScheme
{
...
}
しかし、私はまだコードがColorSchemeと呼ばれる静的クラスの存在に依存しているという事実に直面しています。私の最初の考えは、Outlook2003またはOutlook2007から派生するColorSchemeクラスを作成することでした。
public static class ColorScheme : Outlook2007ColorScheme
{
}
ただし、静的クラスから派生することはできません。
次に考えたのは、静的ColorSchemeクラスを作成し、Outlook2003ColorSchemeおよびOutlook2007ColorSchemeクラスを非静的にすることでした。次に、静的ColorSchemeクラスの静的変数は、「true」または「true」配色:
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#ではできませんので、受け入れられた答えとしてマークできます。同じ質問に対する回答を必要とする他の人は、この質問、受け入れられた回答、および役立つ場合とそうでない場合があるいくつかの回避策を見つけるでしょう。
この質問を閉じたいだけです。
解決 4
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#でクラス名にエイリアスを作成しないで できることはあります:
-
ColorScheme
に依存しているすべての人をusing
ColorScheme
に変更します(エイリアスできないため、コードを変更する回避策) -
ColorScheme
に依存するすべての人をファクトリパターンを使用してポリモーフィッククラスまたはインターフェイスに変更します(エイリアスできないためコード変更の回避策)
ただし、これらの回避策には、既存のコードの破壊が含まれます。オプションではありません。
人々が ColorScheme
クラスの存在に依存している場合、実際に ColorScheme
クラスをコピー/ペーストする必要があります。
つまり、C#でクラス名をエイリアス化することはできません。
これは、エイリアスを定義できる他のオブジェクト指向言語とは対照的です:
ColorScheme = Outlook2007ColorScheme
これで完了です。
他のヒント
元のクラス名を変更する場合、インポートエイリアスを typedef
の代替として使用して、依存コードを書き換えることができます。
using ColorScheme = The.Fully.Qualified.Namespace.Outlook2007ColorScheme;
これは、通常の using
sと同様に、ファイル/ネームスペースの先頭に配置する必要があります。
しかし、これがあなたの場合に実用的かどうかはわかりません。
次のコード行を追加して、クラスのエイリアスを作成できます。
using Outlook2007ColorScheme = YourNameSpace.ColorScheme;
(工場 | シングルトン)、要件に応じて。前提は、クライアントコードが取得している配色を知る必要がないようにすることです。カラースキームをアプリケーション全体に適用する必要がある場合は、シングルトンで十分です。異なる状況で異なるスキームを使用する場合は、おそらくFactoryパターンが最適です。いずれにせよ、配色を変更する必要がある場合、コードを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; }
}
}
これを試してください:
using ColorScheme=[fully qualified].Outlook2007ColorScheme
このコメントを追加するのは、OPが" answer"を受け入れてからずっと後になったユーザーです。 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
}
}
迅速に入力されたコードについてはおologiesび申し上げますが、C#で実行できないとユーザーが誤解しないように、これがどのように実装されるべきかを説明することが望まれます。
やりたい方法にエイリアスを付けることは、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);
}
コードを1行更新することにより、 ColorScheme
の値を更新できます( CurrentColorScheme = Outlook2008ColorScheme;
を使用)。
いくつかの懸念事項:
- すべての新しいメソッドまたはプロパティの定義は、
ColorScheme
クラスとOutlook2007ColorScheme
クラスの2つの場所に追加する必要があります。これは余分な作業ですが、これが真のレガシーコードである場合、頻繁に発生することはありません。ボーナスとして、ColorScheme
のコードは非常に単純なので、考えられるバグは非常に明白です。 - この静的クラスの使用は私には自然に思えません。おそらくレガシーコードを別の方法でリファクタリングしようとしますが、あなたの状況ではそれができないかもしれないことも理解しています。
- 既に置き換えている
ColorScheme
クラスがある場合、このアプローチやその他の問題が発生する可能性があります。そのクラスの名前をColorSchemeOld
などに変更し、CurrentColorScheme = ColorSchemeOld;
を使用してアクセスすることをお勧めします。
基本クラスから何も追加せずにいつでも継承できると思います
public class Child : MyReallyReallyLongNamedClass {}
更新
ただし、 class
自体をリファクタリングする機能がある場合: namespace
が不足しているため、クラス名は通常不必要に長くなります。
ケースが ApiLoginUser
、 DataBaseUser
、 WebPortalLoginUser
である場合、通常は 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
ですが、異なる namespace
であることに注意してください。 PEP-20:Python of Zen :
名前空間は素晴らしいアイデアの1つです-それらをもっとやってみましょう!
これが役立つことを願って
インターフェースの使用に変更することは可能ですか?
おそらく、すべてのクラスが実装する IColorScheme
インターフェースを作成できますか?
これは、Chris Marasti-Georgが示す工場パターンでうまく機能します
非常に遅い部分的な答えです-ただし、同じ名前空間 'Outlook'で同じクラス 'ColorScheme'を定義し、別のアセンブリ(Outlook2003と他のOutlook2007と呼ばれる)で定義する場合は、参照するだけです適切なアセンブリ。