我有一个返回Generic Type列表的方法
List<T> GetResultList<T>()
T是上课。对于每个班级,都有一个会员日期。现在,我想按日期过滤GetResultList中的T列表。有可能吗?
或者,我必须在每个班级都这样做?
更重要的是,在不同的类中,成员应该在过滤器中使用是不同的,即对于class1,我想过滤Date,对于class2,我想过滤Date2。这可以在GetResultList而不是每个类中完成吗?
由于
答案 0 :(得分:1)
(a)最佳选择:创建描述合同的接口(例如,存在Date
属性)并将您的泛型类型约束到该接口。
此选项具有静态类型的好处:使用未实现接口的T
是编译时错误。
interface IDated
{
DateTime Date { get; }
}
List<T> GetResultList<T>() where T: IDated
{
T x;
if (x.Date == DateTime.Today); // You can access T.Date
}
(b)所有其他解决方案都是运行时动态访问。当然,从dynamic
开始,或使用反射按名称访问成员。它们都有缺点,即在编译时没有验证其正确性(即在运行时使用T
而Date
失败)和性能开销。
成员应该在过滤器中使用不同
(a)用一致的界面统一它们并使用上面的选项(a)。
(b)将字段名称传递给动态或基于反射的代码。
(c)传递一个谓词,就像LINQ Where
方法一样。类似的东西:
List<T> GetResultList<T>(Func<T, bool> predicate)
{
T x;
if (predicate(x)) /*...*/;
}
// Usage:
GetResultList<MyObject>(x => x.Date == DateTime.Today);
编辑:如果您不想在来电者网站编码条件,则可以传递值提取器(投影/类似Select
):
List<T> GetResultList<T>(Func<T, DateTime> getDate)
{
T x;
if (getDate(x) == DateTime.Today) /*...*/;
}
// Usage:
GetResultList<MyObject>(x => x.Date);
答案 1 :(得分:0)
如果你知道T可以表示的任何东西都有一个名为Date的属性,那么你可以实现和接口IHasDate(或其他)......然后如果你在你的泛型参数中包含一个条件,那么传入的任何东西都会有T物业可用。
未经测试的代码......
public interface IHasDate
{
DateTime Date { get; }
}
public List<T> GetResultsList<T>()
where T : IHasDate
{
var list = new List<T>();
//Fill list
list.Sort((t1, t2) => t1.Date.CompareTo(t2.Date));
Return t;
}
答案 2 :(得分:0)
传递代表:
GetResultList(x => x.Date2);
并更新您的GetResultList
函数以使用该代理:
List<T> GetResultList<T>(Func<T, Date> dateGetter)
{
return someList.OrderBy(x => dateGetter(x)).ToList();
}
答案 3 :(得分:0)
<强> 1)强>
既然您谈到List<T>
列表中的所有对象都已经有了接口 - 那么经典解决方案就是在类中实现特殊方法(这里T
是{{1} }}):
IClassWithDate
2)但是既然你不想在课程中实现任何逻辑,你可以使用另一种方法 - 使用dynamis :
public interface IClassWithDate
{
DateTime DateForFiltering();
}
internal class classDerrivedFromInterface1 : IClassWithDate
{
public DateTime Date;
public int AnotherField;
public DateTime DateForFiltering()
{
return Date;
}
}
internal class classDerivvedFromInterface2 : IClassWithDate
{
public DateTime Date2;
public int AnotherField;
public DateTime DateForFiltering()
{
return Date2;
}
}
public List<IClassWithDate> GetResultList<IClassWithDate>()
{
var listOfIClassesWithDate = new List<IClassWithDate> { new classDerrivedFromInterface1 { Date = DateTime.MinValue, AnotherField = 2 }, new classDerivvedFromInterface2 { Date2 = DateTime.MinValue, AnotherField = 2 } };
return listOfSimpleClasses.Where(x => x.DateForFiltering() == DateTime.MinValue).ToList();
}
3)与第二次相同,但没有动态(这就是为什么这种方式比2更好)。您应该使用类型转换和对象:
class simpleClass1
{
public DateTime Date;
public int AnotherField;
}
class simpleClass2
{
public DateTime Date2;
public int AnotherField;
}
public List<dynamic> GetResultList()
{
var listOfSimpleClasses = new List<dynamic> {new simpleClass1 {Date = DateTime.MinValue, AnotherField = 2}, new simpleClass2 {Date2 = DateTime.MinValue, AnotherField = 2}};
return listOfSimpleClasses.Where(x =>
{
if (x is simpleClass2)
return x.Date2 == DateTime.MinValue;
if (x is simpleClass1)
return x.Date == DateTime.MinValue;
return false;
}).ToList();