泛型參數必須能夠在編譯時確定的(而不是訴諸類似的功能類型推斷一些其他的語言有)一個類型。所以,你不能只在尖括號之間插入一個函數來得到你想要的類型。
編輯:
現在我知道你想要做什麼,我會建議完全不同的方法。
您提到您正在使用實體框架,並且您正嘗試使用一種方法來獲取不同類型對象的列表。這些對象 - 比如學生和老師 - 必須有一些共同點,但是,否則你不會試圖用相同的方法來檢索它們的列表。例如,您可能只是想顯示一個名稱並將一個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.");
}
現在,有一定的方法來完善這一模式。如果你有很多相關的類,你可能需要使用某種依賴注入框架。另外,您可能會注意到代碼有很多重複。你可以通過做一些事情,而不是通過一個函數(如GetStudentList
或GetTeacherList
)像
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
的用法。
你不能;泛型在編譯時被檢查,這就是整個點。這並不是說沒有更好的方法來完成你所需要的。不要給我們一個沒有道理的建議解決方案,而要告訴我們你想要在高層次上實現什麼。 –