2009-04-17 11 views
2

私はLINQ式でスタティック・リフレクションを勉強しています。静的反射のオンザフライフィールド?

1つのクラスは、あるクラスが別のクラスで行われた静的リフレクションに基づいて1つのクラスにフィールドを生成することは可能ですか?私はここで何度も見たBuilderパターンを特に考えています。私は構築したいクラスに合ったビルダーのフィールドを '生成する'という流暢なハイバネーションスタイルのプロパティー登録をしたいと思います。 Soemthingこのように:

public class Color 
{ 
    private Color() 
    { 
    } 
    public string Name { get; private set; } 

    public class Builder : BuilderBase<Color> 
    { 
     public Builder() 
     { 
      Property(x => x.Name); 
     } 
     public Build() 
     { 
      return built_up_color; 
     } 
    } 
} 

と、このようなコンストラクタ構文をサポートしています。

Color c = new Color.Builder() { Name = "Red" }.Build(); 

このすべてのポイントは、私は色のproperiesを定義繰り返す必要が回数を減らすことです。

public class Color 
{ 
    private Color() 
    { 
    } 
    public string Name { get; private set; } 

    public class Builder 
    { 
     private Color _color = new Color(); 
     public string Name 
     { 
      get { return _color.Name; } 
      set { _color.Name = value; } 
     } 

     public Build() 
     { 
      return _color; 
     } 
    } 
} 

これは確かに動作し、同じ回数のプロパティをリストしますが、より細かく柔軟性が低いと感じます。私はここで何か匿名型yをやることができるはずですね?

答えて

1

ワースは、ColorというクラスをSystem.Drawing.Colorでクラッシュさせることは、おそらく悪い考えであることを指摘しています。

それはある非常に他の人で混乱を招く可能性が

私は指摘しているでしょう(あなたのクラスはさらに混乱を招く可能性があります参照セマンティクスを持っているのに対し、さらに悪いことにSystem.Drawring.Colorは、値のセマンティクスを持っている)何あなたは本当に欲しいですNamed Optional Argumentsです。私は厄介なBuilderクラスを追加することがより手間がかかり、C#4.0になったらこれらのクラスに移行するのがより苦痛になることを示唆しています。代わりに、必要なコンストラクタを作成します(または、クラスの静的ファクトリメソッドと型シグネチャの衝突を避ける必要がある場合)

+0

優れたポイント。私の場合は、実際に部品や車が入る色をモデル化しようとしています。たぶん私は英国の同僚の鉛に従うべきで、名前はColor;) – n8wrl

+1

PartColorを名前として使用することをお勧めします。不変で小さくても構造を作ることを検討したいかもしれませんが、問題を避ける 私はブリットですが、スペリングのプログラミング用語では、帰化したヤンクです。色、同期など) – ShuggyCoUk

0

明示的に宣言する以外はメンバーを生成できません。箇条書きにしてColorのコンストラクタを宣言します。

PS:静的な反射は間違っていると思います。静的な唯一のことは、あなたが参照したいメンバーの検索です。これは良いことだが、それほど遠くない。

+0

感謝を呼び出します。私は色のコンストラクタを持っていましたが、それは再びパラメータを読み込むことを意味しました。あなたは、建築者が「通り抜ける」ことに問題を抱えていますか? – n8wrl

+0

私は問題を見ません(ペダンティックモードがオンの場合を除きます:)。しかし、*私はビルダーを持っていることを知りません。 –

0

値を設定するリフレクションを使用するコードが少なくなります。

トリックはコレクション初期化子を使用することです。タイプセーフです。

public class Color 
{ 
    private Color() 
    { 
    } 
    public string Name { get; private set; } 
    public int Prop2 { get; private set; } 

    public class Builder : Builder<Color> 
    { 
     public Builder() 
     { 
      // possible 
      _instance.Name = "SomeDefaultValue"; 
     } 
    } 
} 

class Builder<T> : IEnumerable<string> 
{ 
    protected T _instance = Activator.CreateInstance(typeof(T)); 

    public void Add<TProperty>(Expression<Func<T, TProperty>> prop, TProperty value) 
    { 
     StaticReflection.GetPropertyInfo(prop).SetValue(_instance, value, null); 
    } 

    public static implicit operator T(Builder<T> builder) 
    { 
     return builder.Build(); 
    } 

    public T Build() 
    { 
     return _instance; 
    } 

    IEnumerator<string> IEnumerable<string>.GetEnumerator() 
    { 
     // e.g. return iterator over the property names 
     throw new NotImplementedException(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return ((IEnumerable<string>)this).GetEnumerator(); 
    } 
} 

と構文をあなたの答えのための

var color = new Color.Builder 
{ 
    { x => x.Name, "foo" }, 
    { x => x.Prop2, 5 } 
}.Build(); 

// or 

var color = new Builder<Color> 
{ 
    { x => x.Name, "foo" }, 
    { x => x.Prop2, 5 } 
}.Build(); 

// or 

Color color = new Builder<Color> 
{ 
    { x => x.Name, "foo" }, 
    { x => x.Prop2, 5 } 
};