2011-10-11 19 views
0

我有一個問題。我有一個方法(過濾器),我想通過T dynamic.but它dosen`t accept.how我可以做到嗎?如何在Ilist <T>中通過T動態?

public List<T> Filter<T>(string TypeOfCompare) 
    { 


     List<T> ReturnList2 = new List<T>(); 
     return ReturnList2; 
    } 
IList MakeListOfType(Type listType) 
    { 
     Type listType1 = typeof(List<>); 
     Type specificListType = listType.MakeGenericType(listType1); 

     return (IList)Activator.CreateInstance(specificListType); 
    } 
Filter < ConstructGenericList(h) > ("s"); 
+1

你不能;泛型在編譯時被檢查,這就是整個點。這並不是說沒有更好的方法來完成你所需要的。不要給我們一個沒有道理的建議解決方案,而要告訴我們你想要在高層次上實現什麼。 –

回答

0

泛型參數必須能夠在編譯時確定的(而不是訴諸類似的功能類型推斷一些其他的語言有)一個類型。所以,你不能只在尖括號之間插入一個函數來得到你想要的類型。

編輯:

現在我知道你想要做什麼,我會建議完全不同的方法。

您提到您正在使用實體框架,並且您正嘗試使用一種方法來獲取不同類型對象的列表。這些對象 - 比如學生和老師 - 必須有一些共同點,但是,否則你不會試圖用相同的方法來檢索它們的列表。例如,您可能只是想顯示一個名稱並將一個ID用作關鍵字。

在這種情況下,我會建議定義一個接口,該接口具有您實際需要的Student,Teacher等通用屬性,然後返回該接口類型的列表。在該方法中,您基本上會使用工廠模式的變體。

所以,你可以這樣定義一個接口:

public interface INamedPerson 
{ 
    int ID { get; } 
    string FirstName { get; } 
    string LastName { get; } 
} 

讓你的實體實現此接口。自動生成的實體(典型值)的部分類,所以在你自己的,新的代碼文件(在自動生成的代碼文件本身),你會做這樣的事情:

public partial class Student : INamedPerson 
{ 
    public int ID 
    { 
     get 
     { 
      return StudentId; 
     } 
    } 
} 

public partial class Teacher : INamedPerson 
{ 
    public int ID 
    { 
     get 
     { 
      return TeacherId; 
     } 
    } 
} 

現在,如果您已經擁有它,您甚至可能不需要添加ID屬性。但是,如果每個類中的標識屬性不同,則此適配器可以作爲實現所需接口的一種方式。

然後,該方法本身,一個例子是:

public List<INamedPerson> MakeListOfType(Type type) 
{ 
    if (type == typeof(Student)) 
    { 
     // Get your list of students. I'll just use a made-up 
     // method that returns List<Student>. 
     return GetStudentList().Select<Student, INamedPerson>(s => (INamedPerson)s) 
           .ToList<INamedPerson>(); 
    } 
    if (type == typeof(Teacher)) 
    { 
     return GetTeacherList().Select<Teacher, INamedPerson>(t => (INamedPerson)t) 
           .ToList<INamedPerson>(); 
    } 
    throw new ArgumentException("Invalid type."); 
} 

現在,有一定的方法來完善這一模式。如果你有很多相關的類,你可能需要使用某種依賴注入框架。另外,您可能會注意到代碼有很多重複。你可以通過做一些事情,而不是通過一個函數(如GetStudentListGetTeacherList)像

public List<INamedPerson> GetListFromFunction<T>(Func<IEnumerable<T>> theFunction) where T : INamedPerson 
{ 
    return theFunction().Select<T, INamedPerson>(t => (INamedPerson)t).ToList<INamedPerson>(); 
} 

當然,使用此功能,需要再次傳入的類型在編譯時是已知的。但是,在某些時候,你將不得不決定一個類型,所以也許這是適當的時間。此外,您可以通過在方法調用時忽略泛型類型來讓自己的生活更簡單一些;只要您傳遞的函數不帶任何參數並返回實現了INamedPerson的相同類型對象的IEnumerable,編譯器就可以找出通用類型T的用法。

+0

我有一個複選框,項目是學生,老師,..他們是我的實體。我想當用戶選擇其中一個我得到(例如用戶選擇學生)名稱和通過MakeListOfType方法我做一個學生的名單,我想通過列表到我的過濾方法,並做一些事情,我可以做什麼? –

+0

@@ Andrew真的很感謝。 –

1
IList MakeListOfType(Type listType) 
{ 
    Type listType1 = typeof(List<>); 
    Type specificListType = listType.MakeGenericType(listType1); 

    return (IList)Activator.CreateInstance(specificListType); 
} 

應該反過來想,你應該叫MakeGenericType在泛型類型定義,而不是在泛型類型參數。因此,代碼變成這樣:

IList MakeListOfType(Type elementType) 
{ 
    Type listType = typeof(List<>); 
    Type specificListType = listType.MakeGenericType(elementType); 

    return (IList)Activator.CreateInstance(specificListType); 
} 

(請注意,我改變了變量的名稱,使代碼更清晰)