2016-07-07 9 views
3

は私がコンストラクタパラメータを示す式を記述する方法はありますか?

Expression<Func<Foo, string>> member = foo => foo.Bar; 

を書いて、メンバーBarを指す表現を得ることができ、次のタイプ

class Foo 
{ 
    public string Bar { get; private set; } 

    public Foo(string bar) 
    { 
     Bar = bar; 
    } 
} 

を考えます。

コンストラクタパラメータbarを指す式を何とか書くことができますか?


これで私の目標は変更することが弾力性のある方法で、コンストラクタのパラメータを示すことができるようにすることです。たとえば、コンストラクタをリファクタリングするときに、パラメータの名前を変更することができます。これは式に引き継がれます。私はそれを削除した場合、式はビルドエラーを起こす必要がある、など


アップデート - 私は有効にしたいの使用の更なる明確化:

(拡張メソッドを考えてみて、本当に問題ではありません

public static void DoSomething<T>(this object o, Expression<Func<T, object>> expr) 
{ 
    // ... 
} 
:それは次のように定義されていた場合

new object().DoSomething<Foo>(foo => foo.Bar); 

:このように呼んだもの)に210

プロパティBarにアクセスして、拡張メソッドの本体の内部でさまざまなことを行うことができます。たとえば、他の場所からの入力を受けて、その値を設定することができます。具体的なユースケースは、このような何かをしAutoMapper、次のとおりです。

CreateMap<FooDto, Foo>() 
    .ForMember(dest => dest.Bar, cfg => cfg.MapFrom(src => src.BarSrc)); 

表現dest => dest.Barは、我々は上の特別な設定を適用すること(Foo上)の特性を示し、src => src.BarSrcは(FooDto上の)プロパティを示していると我々価値を取りたい。実際にFooDtoFooにマップするとき、AutoMapperはソースインスタンスからBarSrcの値を抽出し、宛先インスタンスのBarを2つの式を使用してその値に設定することができます。

同様に、私はあなたの正確な程度完全かどうか分からない

CreateMap<FooDto, Foo>() 
    .ForCtorParam(dest => /* what do I put here to indicate the bar ctor param? */, 
     cfg => cfg.MapFrom(src => src.BarSrc)); 

(現在のAPIは私に不格好感じる.ForCtorParam("bar", ...)です。)

+0

あなたはC#6を指していると思っています。その場合は、あなたの投稿を編集してそれを反映させるべきです。 – Rahul

+0

@Rahulこの記事のC#6はなんですか? – juharr

+0

@Rahul:C#バージョンについてはあまり気にしませんが、C#6が問題を解決する必要があるかもしれません。しかし、これは本質的な問題ではありません。以前のバージョンのソリューションも大歓迎です。 –

答えて

3

を言うために私が行うことができるようにしたい何か、ですあなたのコードの中のパラメータの名前に頼っているようです(リファクタリング時には検出されません)。

あなたはパラメータのハードコードされた名前を使用しないようにしたい場合は、C#6.0でnameofを使用することができます。

public Foo(string bar) 
{ 
    var nameOfBarParameter = nameof(bar); 
    Bar = bar; 
} 

注パラメータの宣言の有効範囲内でこれだけの作品は、身体、すなわちことこの場合のコンストラクタの

コンストラクタの外にあるパラメータの名前にアクセスする必要がある場合、表現を使用する方法はないと思います。あなたが構築している場合

var ci = typeof(Foo).GetConstructor(new[] { typeof(string) }); 
var parameterName = ci.GetParameters()[0].Name; 
+0

これはコンストラクタのスコープ内でローカルにしか動作しません。私はコンストラクタの内部だけでなく、この式をどこでも使用できるようにしたいと思います。 (具体的な使用例については、私のコメントを参照してください。) –

0

がわからない、これはあなたの必要性に合っている場合、しかし:あなたは、もちろん、常に関連ParameterInfoとパラメータ名を取得するためにリフレクションを使用することができます(ただし、あなたはパラメータ位置変更していないに依存します)式ツリー:

Expression<Func<Foo>> expr =() => new Foo("dummy"); 

barを利用し、その後:

ParameterInfo barParameter = ((NewExpression)(expr.Body)).Constructor.GetParameters()[0]; 

は(ゼロ次)コンストラクタの表現でありますパラメータ。

関連する問題