2012-08-06 91 views
5

我有以下的輔助方法:沒有拳擊或類型參數轉換爲通用類型參數

public static T CreateRequest<T>() 
    where T : Request, new() 
{ 
    T request = new T(); 
    // ... 
    // Assign default values, etc. 
    // ... 
    return request; 
} 

我想在另一個助手使用這種方法從另一個方法內部:

public T Map<F, T>(F value, T toValue) 
    where T : new() 
    where F : new() 
{ 
    if (typeof(T).BaseType.FullName == "MyNamespace.Request") 
    { 
     toValue = MyExtensions.CreateRequest<T>(); 
    } 
    else 
    { 
     toValue = new T(); 
    } 
} 

但後來我得到的錯誤:

The type 'T' cannot be used as type parameter 'T' in the generic type or method 'MyExtensions.CreateRequest()'. There is no boxing conversion or type parameter conversion from 'T' to 'MyNamespace.Request'.

有沒有辦法投了「T」型,這樣的createRequest竟被d使用它沒有問題?

編輯:

我知道我可以做兩件事情:

  • 鬆開的createRequest約束或
  • 緊約束上的地圖。

但我不能做第一次,因爲在CreateRequest我的用戶屬性的請求類,我不能做第二次,因爲我用其他類型(不從繼承請求)與地圖功能。

+0

它的意思是:「要麼或無」 – 2012-08-06 06:59:57

回答

4

對於這種情況,你需要放鬆的CreateRequest通用的限制。

public static T CreateRequest<T>() 
    where T : new() 
{ 
    if(!typeof(Request).IsAssignableFrom(typeof(T))) 
     throw new ArgumentException(); 

    var result = new T(); 
    Request request = (Request)(object)result; 
    // ... 
    // Assign default values, etc. 
    // ... 
    return result ; 
} 

這可能是痛苦的,因爲你失去了編譯時間驗證這個參數。

或者如果您想在其他地方使用CreateRequest方法,則僅爲此方案創建非通用重載。

public static object CreateRequest(Type requestType) 
{ 
    if(!typeof(Request).IsAssignableFrom(requestType)) 
     throw new ArgumentException(); 

    var result = Activator.CreateInstance(requestType); 
    Request request = (Request)result; 
    // ... 
    // Assign default values, etc. 
    // ... 
    return result ; 
} 
+0

這是爲什麼這個雙重演員需要? '(Request)(object)result;' – 2012-08-06 06:57:17

+0

很好的捕獲'.IsAssignableFrom'!比字符串比較更好! – 2012-08-06 06:58:06

+0

雙演員是編譯器告訴他,你知道你在做什麼,你負責它。沒有它它不會工作,如果上面確保這將工作。 – Rafal 2012-08-06 06:59:57

3

您已經聲明T的類型爲RequestCreateRequest方法;另一方面,在Map方法中,你沒有這樣的約束。嘗試改變的Map的聲明:

public T Map<F, T>(F value, T toValue) 
where T : Request, new() 
where F : new() 
+0

的問題是我用的類型,不請求從繼承地圖功能,所以我不能設置此contraint。 – 2012-08-06 06:56:47

+0

然後,您可以嘗試從CreateRequest函數中刪除請求約束。 – daryal 2012-08-06 06:58:22