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);

不是有效的语法。您可以拥有“全部或全部”。

因此,如果要推断Tand ,则需要以其他方式TT传递当前包含的信息。TV例如,一种选择是将属性的类型作为参数传递:

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 回答