2012-01-10 6 views
1

経由リテラルを取得しよう:私は次のコードがあると反射


Container.cs

public class Container 
{ 
    public readonly string IdType; 

    public Container(string aIdType) 
    { 
     IdType = aIdType; 
    } 
} 

SuperContainerAは.cs

public class SuperContainerA : Container 
{ 
    public SuperContainerA(/*x parameters*/) : base("A") {} 
} 

をSuperContその上でainerB.cs

public class SuperContainerB : Container 
{ 
    public SuperContainerB( /*y parameters*/) : base("B") {} 
} 

SuperContainerToTheInfinityAndBeyond.cs

public class SuperContainerB : Container 
{ 
    public SuperContainerB( /*y parameters*/) : base("It's Over 9000!") {} 
} 

、私が取得しようとしていること"""B"ですそれらはコンストラクタからTypeIdに送信されています。

ここでキャッチするのは、プログラムの初期化中に、それらのクラスのインスタンスを作成する前にこれらの値を取得する必要があるため、ここでリフレクションを使用することが最善の策だと思いました。 (注:各コンストラクタのパラメータの数が同じであれば、値を取得するクラスのインスタンスを作成することは有効ですが、変更することができます:

リフレクションを使用して(ソースコードのようなものが見える場合は、Regexを使って値を取得することができます)(参考:ソースをリソースファイルとしてとして私のプログラムに組み込むことはオプションではありません:P)

私は当時つかむために、後にリフレクションを使用することができるように、その後に値と命名規則を保持するための定数を宣言すると思っていますので。以下のような...

public class SuperContainerA 
{ 
    public const string ctIdType = "A"; 
} 

public class SuperContainerB 
{ 
    public const string ctIdType = "B"; 
} 

をmething ...しかし、これらのconstsは宣言している場合されている場合、私は私がチェック助けるために何かを持っていないので、私は、これがこの問題への最善のアプローチであるかどうかわからないんだけど彼らはコンパイル時に適切な名前を得ました。

実際には、言語に何らかの静的継承があると、この状況では多くの助けになりますが、静的継承は治療法よりも痛みを感じているプログラマーもいます。

とにかく、私は代替手段を探しています。どんな考えも大歓迎です。

+1

あなたは正確に何をしようとしていますか?オブジェクトを作成する前に値を知ることから得られるメリットは何ですか? – cadrell0

答えて

4

レスキューアトリビュートへの属性!

public class IdTypeAttribute: Attribute 
{ 
    public string IdType { get; private set; } 

    public IdTypeAttribute(string idType) 
    { 
     IdType = idType; 
    } 
} 

[IdType("B")] 
public class SuperContainerB: Container 
{ 
    // whatever you like... 
} 

これで、反射を介して属性にアクセスできます。行うのに十分簡単に​​...

var type = typeof(SuperContainerB); 
var attribute = (IdTypeAttribute)type.GetCustomAttributes(
    typeof(IdTypeAttribute), false)[0]; 
var idType = attribute.IdType; 
+1

あなたの答えをスーパーヒーローであるかのように提示する+1。 – ean5533

+0

属性について完全に忘れました。ええ、彼らはこの特定の問題のための良いエスケープルートになるでしょう。コンパイル時間のバリデーションもいくつか手に入ります。ありがとう。 – Canella

1

なぜ単にあなたがそれに関連付けられたいと思われる文字列値をルックアップするために、具体的な型を使用していませんか?

public class SuperA : Container 
{ 
    public string IdType { get { return IdTypeFactory.Get(GetType()); } } 
} 

public static class IdTypeFactory 
{ 
    public static string Get(Type containerType) { ... } 
} 

このソリューションの主な利点は、すべての文字列リテラルを1つの中央に集めることです。あるいは、抽象スーパークラスを使用してください。

+0

これは有効なオプションです。ありがとうございます。私はそれを使用することを検討します。私は一緒に物事を維持するのが好きですが、これは素晴らしい解決策になる可能性があります。 – Canella