2011-06-14 70 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; 

然後,您可以開始分析表達式。儘管如此,你將不得不做更多的運行時測試和安全檢查。