我有以下扩展方法断言属性(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上调用了ShouldHave,为什么不必明确指定它。 TT是表达式(x.Id)中引用的属性的类型。
答案 0 :(得分: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
类型参数,这是您需要在调用站点显式指定泛型参数的原因。如果你需要这个论点,那你就不走运了。
答案 1 :(得分:1)
只有在方法调用中指定了 no 泛型参数时,才能自动推断类型参数。即,这个:
myDto.ShouldHave<, RequiredAttribute, >(x => x.Id);
是无效的语法。你可以“全有或全无”。
因此,如果您想推断T
和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));
答案 2 :(得分:0)
试试这个:
public static void ShouldHave<TV>(this object obj, Expression<Func<object, object>> exp) {...}
你应该会发现exp
现在包含一个由强制转换为对象的真实表达式。在你的方法中,剥离演员表如下:
Expression realExp = ((UnaryExpression) exp).Operand;
然后你就可以开始分析表达了。但是,您必须进行比原始方法更多的运行时测试和安全检查。