我正在使用以下两个不同的类调用泛型方法:
FillDataPointsInOrder<Metrics>(dataPoints.Where(O => O.SortOrder != null).OrderBy(O => O.SortOrder));
FillDataPointsInOrder<Metric>(angieStatsCmp.GetDataColumns());
private void FillDataPointsInOrder<T>(IEnumerable<T> dataPoints)
{
foreach (T dpoint in dataPoints)
{
if (!dpoint.IsPhone)
FillDrp(this.EmailDrp, dpoint.Name, dpoint.MetricId.ToString(), dpoint.VName);
if (dpoint.IsPhone && this.IsPhoneShop)
FillDrp(this.PhoneDrp, dpoint.Name, dpoint.MetricId.ToString(), dpoint.VName);
}
}
在“FillDataPointsInOrder”方法中我收到编译错误:
'T' does not contain a definition for 'IsPhone' and no extension method 'IsPhone' accepting a first argument of type 'T' could be found (are you missing a using directive or an assembly reference?)
Name,MetricId和VName属性的相同错误。 不确定为什么T无法访问Metrics和Metric的属性。 如果我从泛型方法中删除代码并将其直接写入foreach而不是dataPoints,那么它可以正常工作。
有人可以告诉我这里有什么问题吗?
答案 0 :(得分:2)
FillDataPointsInOrder
仅知道将使用T
调用它。 T
实际上可以是字符串,整数或任何东西。
如果要在T上调用属性,则必须使用where
约束。
但在这种情况下看起来你的方法甚至不需要是通用的。
如果Metric
和Metrics
共享基类或具有所需属性的接口:
interface IMetric {
bool IsPhone {get; }
}
你可以拥有:
private void FillDataPointsInOrder(IEnumerable<IMetric> dataPoints)
请注意,IEnumerable是协变的,因此如果Metric
是IMetric
,则IENumerable<Metric>
是IEnumerable<IMetric>
答案 1 :(得分:2)
如果你想这样做,你至少需要告诉编译器关于T的东西。您是否有一个界面,其中包含您的类实现的IsPhone,Name,MetricId等成员?
如果是这样,您可以在类定义中添加“where”约束:
public class Something<T> where T : ISomethingElse
...其中ISomethingElse是实现IsPhone的接口。