我有一堂课电影:
internal class Movie
{
public string Name { get; set; }
public string Year { get; set; }
}
我有这段代码:
var Movies = CreateMovies(); //IEnumerable<Movie>
var sorter = new Sorter<Movie>();
sorter.AddSort(Movies, m => m.Year , a=>a.Name ,.....as many as I want....);
这是Sorter
类:
class Sorter<T>
{
public void AddSort(IEnumerable<T> movs, params Expression<Func<T, object>>[] funcs)
{
/*...*/
movs.OrderBy(d=>d.); //<----- here is the problem : where is the columns ?
}
}
问题:
当我需要d
上的智慧时,它会告诉我:
我不明白为什么T
不会被推断为Movie
:
查看有多少位置推断T
是Movie
:
如何让这些电影字段显示,而不更改为Ienumerable<Movies>
?
答案 0 :(得分:8)
在编译Sorter
类时,编译器不知道它将是什么类型,因此无法判断将使用它的用户是否具有Year
属性或不。
但是,您可以使用where constrains:
class Sorter<T> where T: Movie
编译器知道给定的T
类将具有Year
属性以及其他属性
在泛型类型定义中,where子句用于指定 对可用作类型参数的类型的约束 泛型声明中定义的参数。例如,你可以 声明一个泛型类MyGenericClass,这样就是type参数 T实现IComparable接口:
因为它说你甚至不必做
class Sorter<T> where T: Movie
我们可以满意
class Sorter<T> where T: ImyInterface
和ImyInterface
将包含Name
和Year
的属性。
答案 1 :(得分:1)
我没有尝试过这段代码,但我认为你应该能够做到以下几点:
foreach(var func in funcs)
movs = movs.OrderBy(func);
简单地将排序函数委托给OrderBy方法,而不关心那些函数是什么以及什么类是T(这违背了泛型的目的)。
答案 2 :(得分:0)
以下是我如何解释您的问题和意图:
1&GT;您正在使用Sorter类与非泛型Sorter,因为您打算使用此类来处理多个类型。
2 - ;因为对于AddSort方法,您希望它基于Movie类成员,因此表明您将使用基于Movie类的派生类,如XYXMovie:Movie等,将使用Sorter。
如果我的上述观察是正确的,那么你需要将Sorter类绑定到基类“Movie”,以便它可以处理从类Movie派生的所有类型。
为了做到这一点,你必须使用where约束,比如类Sorter,其中T:Movie。
这使得您的Sorter类与基类Movie绑定,但可以处理其所有子类。