2011-06-14 64 views
3

我有断言属性(同上)包含一个指定的属性(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被调用T为什么不需要明确地指定它。 TT是表达式(x.Id)中引用的属性的类型。

+0

什么'TV'(第二泛型参数)的点? – 2011-06-14 10:51:10

+0

它是必需属性的类型。 – 2011-06-14 10:53:40

+0

@ba__friend:再看看,他们有三个。 – 2011-06-14 10:56:23

回答

1

类型自变量的自动推断仅在方法调用中指定泛型参数时才有效。即:

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

是无效的语法。你可以拥有“全部或全部”。

因此,如果您想推断TTT,则需要以其他方式传递当前包含在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)); 
+0

我选择你的建议稍作修改:public static void ShouldHave (this T obj,Expression > exp,params Type [] attributes) – ThomasArdal 2011-06-16 05:59:01

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类型的说法,这是你需要在调用点明确指定通用参数的原因。如果你需要这个说法,那么你的运气不好。

+0

但是'T'和'TT'不会被删除 – oliholz 2011-06-14 10:54:12

+1

@oliholz是的,他们在呼叫站点。谁在乎它们在定义中是否仍然是必需的? – 2011-06-14 10:55:02

+0

啊没关系,明白了。 – oliholz 2011-06-14 10:57:13

0

试试这个:

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

您应该发现exp现在由被强制转换为对象包围的真实表达。在您的方法中,剥离演员如下:

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

然后,您可以开始分析表达式。尽管如此,你将不得不做更多的运行时测试和安全检查。