1

我正在调用具有两个不同类的通用方法,如下所示:

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 编写它,它工作正常。

有人可以建议这里有什么问题吗?

4

2 回答 2

2

FillDataPointsInOrder只知道它会被调用TT实际上可以是字符串、整数或任何东西。

如果要调用 T 上的属性,则必须使用where约束。

但在这种情况下,您的方法看起来甚至不需要是通用的。如果两者都Metric共享Metrics具有所需属性的基类或接口:

interface IMetric {
  bool IsPhone {get; }
}

你可以有:

private void FillDataPointsInOrder(IEnumerable<IMetric> dataPoints) 

注意 IEnumerable 是协变的,所以如果Metric是 a IMetricIENumerable<Metric>IEnumerable<IMetric>

于 2013-09-30T07:48:37.507 回答
2

如果你想这样做,你至少需要告诉编译器一些关于 T 的信息。您是否有一个接口,其中包含您的类实现的 IsPhone、Name、MetricId 等成员?

如果是这样,您可以在类定义中添加“位置”约束:

public class Something<T> where T : ISomethingElse

...其中 ISomethingElse 是实现 IsPhone 的接口。

于 2013-09-30T07:50:25.360 回答