3

プロパティ(Id)に指定された属性(TV)が含まれていることをアサートする次の拡張メソッドがあります。

public static void ShouldHave<T, TV, TT>(this T obj, Expression<Func<T, TT>> exp) {...}

メソッドは次のように呼び出すことができます。

MyDto myDto = new MyDto();
myDto.ShouldHave<MyDto, RequiredAttribute, int>(x => x.Id);

うまくコンパイルされます。メソッド署名から T と TT を削除できるかどうか疑問に思っていました。T は T で ShouldHave が呼び出されるため、明示的に指定する必要がないからです。TT は、式 (x.Id) で参照されるプロパティの型です。

4

3 に答える 3

2

以下がコンパイルされます。

public static void ShouldHave<T, TT>(this T obj, Expression<Func<T, TT>> exp)
{...}

MyDto myDto = new MyDto();
myDto.ShouldHave(x => x.Id);

これにより、型引数が省略されTVます。これが、呼び出しサイトでジェネリック引数を明示的に指定する必要がある理由です。この引数が必要な場合は、運が悪いです。

于 2011-06-14T10:53:21.573 に答える
1

型引数の自動推論は、メソッド呼び出しでジェネリック引数が指定されていない場合にのみ機能します。つまり、これ:

myDto.ShouldHave<, RequiredAttribute, >(x => x.Id);

は有効な構文ではありません。「オール オア ナッシング」のどちらかを選択できます。

Tしたがって、 と を推論したい場合はTT、現在 に含まれている情報を別の方法で渡す必要がありますTV。たとえば、1 つのオプションは、属性のをパラメーターとして渡すことです。

public static void ShouldHave<T, TT>(this T obj, 
                                     Expression<Func<T, TT>> exp, 
                                     Type attribute) {...}

(明らかに、これには、ShouldHave の実装の変更が必要になります)。

次に、次のようにメソッドを呼び出すことができるはずです。

MyDto myDto = new MyDto();
myDto.ShouldHave(x => x.Id, typeof(RequiredAttribute));
于 2011-06-14T11:03:10.197 に答える
0

これを試して:

public static void ShouldHave<TV>(this object obj, Expression<Func<object, object>> exp) {...}

expオブジェクトへのキャストで囲まれた実際の式で構成されていることがわかるはずです。メソッド内で、次のようにキャストを取り除きます。

Expression realExp = ((UnaryExpression) exp).Operand;

その後、式の分析を開始できます。ただし、元の方法よりも多くの実行時テストと安全性チェックを行う必要があります。

于 2011-06-14T11:01:44.533 に答える