2012-04-22 10 views
0

これは実装方法を理解できなかった興味深い概念です。 (私はデコレータパターンを展開する必要がある大学の割り当てに関連しています)。クラス内のすべてのフィールドに関数を適用する

私は仮定し、しかし、コンパイルされませんそれより下ラフC#のコードを書いて、私は面であなたがconcatFields方法を達成するであろうどのようにクラス

Class A { 
    public int A { get; set; } 
    public string B { get; set; } 
    public float C { get; set; } 

    public string concatFields() { 
     string sample = null; 
     foreach (Field f in this) { 
      sample += f.ToString(); 
     } 
     return sample; 
    } 
} 

がありますか?クラスのフィールドを反復して(フィールドの名前を知らずに)ToString()をそれぞれ呼び出す方法はありますか?

例Bのシナリオでは、同じタイプであれば、すべてのフィールドで同じ方法をどのように適用しますか。助けのための

乾杯男を、私はC#でこれをタグ付けされたが、

+1

あなたが探しているコンセプトは「リフレクション」 –

+0

[dotnetpearls](http://www.dotnetperls.com/reflection-field)のこの例を参照してください。これは、リフレクションを使用しているものを正確に行うための非常に簡単な例(コード付き)です。 – vpiTriumph

答えて

1

あなたは、reflectionを使用し、あなたのクラスのメタデータを反復し、リフレクションAPIを通じてフィールドを引くことができます。明らかに、コストはそれに付随しています:リフレクションの使用はフィールドに直接アクセスするよりも遅いです。時にはかなり。しかし、あなたは確かにそれを行うことができます。次に例を示します。

MyClass obj = new MyClass(); 
// Set fields in the obj... 
var fields = typeof(MyClass).GetFields(System.Reflection.BindingFlags.GetField); 
StringBuilder res = new StringBuilder(); 
foreach (FieldInfo f in fields) { 
    var val = f.GetValue(obj); 
    if (val != null) res.Append(val.ToString()); 
} 
Console.WriteLine(res.ToString()); 

FieldInfoクラスは、そのようNameTypeなど多くの有用な性質を、公開し、あなたの処理に含めるフィールドを選択せ、そして無視するフィールド。

+0

'.GetFields(System.Reflection.BindingFlags.GetField)'を使うことは非常に重要です。そうしないと、getterを持たないフィールドを読み込もうとするExceptionが発生します。 –

+0

@ErikPhilips重要なお知らせをありがとう!補足として、このような100%の変更がある場合は、編集してください。編集者が変更を気に入らない場合は、いつでも編集内容を元に戻すことができます。再度、感謝します! – dasblinkenlight

0

を適用することができ、他のどのようなタグがわからない辞書にあなたの「フィールド」を入れてきました。

そして、ここで辞書を反復処理する方法は次のとおりです。What is the best way to iterate over a Dictionary in C#?

+2

私は彼らが手作業を避けたいと思う。彼らはおそらく反射を使用する必要があります。 – ChaosPandion

0

.NET/C#では、タイプイントロスペクションはSystem.Reflection名前空間で処理されます。これにより、型に関する情報を取得し、コンパイル時に不明なメソッドを動的に呼び出すことができます。

どのようにconcatFieldsメソッドを実現しますか?クラスのフィールドを反復して(フィールドの名前を知らずに)ToString()をそれぞれ呼び出す方法はありますか?あなたはすべてのフィールドに同じ方法を適用する方法を例Bのシナリオでは

public string concatFields() { 
    string sample = null; // a StringBuilder would be a better choice here 
    foreach (FieldInfo f in this.GetType().GetFields()) { 
     obj fieldValue = f.GetValue(); 
     if (fieldValue != null) sample += fieldValue.ToString(); 
    } 
    return sample; 
} 

は、彼らは同じ型だった提供しました。

あなたは、コンパイル時にタイプがわかっている場合は、あなたがそれにキャストすることができます

foreach (FieldInfo f in this.GetType().GetFields()) { 
    MyType myType = (MyType)f.GetValue(); 
    myType.MyMethod(); 
} 

それとも、あなたが動的反射を経由して呼び出すことができます。

foreach (FieldInfo f in this.GetType().GetFields()) { 
    object fieldValue = f.GetValue(); 
    MethodInfo mi = fieldValue.GetType().GetMethod("MyMethod"); 
    mi.Invoke(fieldValue, null); // no parameters to MyMethod 
} 
0

これは私がどうなるかでありますこれは:

class A 

{ 
    public int A { get; set; } 
    public string B { get; set; } 
    public float C { get; set; } 

    public string[] concatFields() 
    { 
     var v = from f in this.GetType().GetFields() select f; 
     IList<string> fields = new List<string>(); 
     foreach (var f in v) 
     { 
      fields.Add(f.GetValue(this).ToString()); 
     } 
     return fields.ToArray<string>(); 
    } 
} 
関連する問題