2017-08-02 65 views
2

列表T中的通用方法我不知道,即使它是可能的,但在這裏,我嘗試添加項目問題List<T>如下添加物品到

public static SelectList ToSelectList<T>(List<T> addlist) where T : new() 
{ 
    addlist.Insert(0, new T { Id = -1, Name = "SELECT" }); 
    var list = new SelectList(addlist, "Id", "Name"); 
    return list;     
} 

new T { Id = -1, Name = "SELECT" }拋出的錯誤是可以添加項目List<T>

+2

你怎麼能指望它的工作?這個世界上有些類沒有'Id'和'Name'屬性。如果'T'是'System.IO.Stream',那麼它會怎麼做 ? –

+0

您的代碼進一步限制了T,因爲它需要屬性ID和名稱。 – StuartLC

+0

我通過的那些實例有Id和Name我不確定是否用於所有類,因此我們假設我的基類有這兩個屬性 – Gayan

回答

3

的問題是, ,通過一般的約束,你已經聲明T作爲具有默認構造函數的任何對象。

編譯器在編譯時執行類型檢查,而T不一定具有屬性IdName

一種解決方案是

  • 創建一個接口,它確實有IdName
  • 修改每一個兼容類,所以它實現了這個接口。
  • 爲您的函數添加另一個通用約束,要求使用類型參數來實現此接口。

的編譯例子:

public interface IEntity 
{ 
    int Id {get; set; } 
    string Name {get; set; } 
} 

class Widget : IEntity 
{ 
    public int Id {get; set; } 
    public string Name {get; set; }  

    public string SomeOtherProperty { get; set; } 
} 

public static SelectList ToSelectList<T>(List<T> addlist) where T : IEntity, new() 
{ 
    addlist.Insert(0, new T { Id = -1, Name = "SELECT" }); 
    var list = new SelectList(addlist, "Id", "Name"); 
    return list; 

} 

// In your code 
List<Widget> widgetList = new List<Widget>(); 
ToSelectList(widgetList); 
+0

偉大的解決方案謝謝你的答案 – Gayan

2

您的代碼存在的問題是您不知道T是什麼以及它具有哪些屬性。 new是不夠的,因爲你的通用約束。它所指定它:

新的約束規定,在一個泛型類聲明的任何類型的參數必須有一個公共的無參數的構造函數

如果你想要去的,只是實例T類型的對象,然後見:Create instance of generic type?

但什麼可能是更好的只是創建具有這些特性的接口,指定您的函數獲取該類型的列表,然後只需實例化類型的對象:

public static SelectList ToSelectList(List<YourInterface> addlist) 
{ 
    addlist.Insert(0, new YourDerived { Id = -1, Name = "SELECT" }); 
    var list = new SelectList(addlist, "Id", "Name"); 
    return list;  
}