繁体   English   中英

约束通用函数缺少扩展方法

[英]missing extension method on constrained generic function

我的问题代码是这样的:

public void MyMethod<U, T>(U Array) where U : List<T>
{
  var sum = Array.Sum();
}

我得到的编译时间错误是这样的:

错误CS1929'U'不包含'Sum'的定义,最佳扩展方法重载'Queryable.Sum(IQueryable)'需要类型为'IQueryable'的接收器

这是.NET Framework 4.6的Visual Studio 2015年这类似于这个问题在这里 ,但我不知道,如果同样的答案是有效的,因为编译器可以看到该方法被明确限制。

任何人都可以给我一些关于为什么我得到这个错误的指示吗?

编辑:

示例代码可以进一步简化:

public void MyMethod<T>(List<T> myList)
{
  var sum = myList.Sum();
}

的重载Sum不具有参数的非通用重载Sum其中IEnumerable已知是数字类型之一,例如:

public static int Sum(IEnumerable<int> source);
public static double Sum(IEnumerable<double> source);
//etc.

允许源序列为任何类型的泛型重载都需要一个选择器,该选择器将项目投影为数值。

为了增加Servy的出色答案,您可以将选择器传递给要在Sum使用的方法,如下所示:

public void MyMethod<T, U>(U items, Func<T, int> selector) where U : List<T>
{
    var sum = items.Sum(selector);
}

并这样称呼它:

MyMethod<int, List<int>>(l, i => i);

Servy的回答是它必须是数字类型,但不是为什么,让我们检查一下。

给定以下功能模板:

public T SomeMethod<T>(List<T> items) where T : int { }

这是一个简单的操作,泛型被限制为特定类型,因此不需要泛型(用int替换T ,并且其行为相同)。

现在,假设数字类型的类型系统具有一个称为“ NumericType”的通用基类:

public T SomeMethod<T>(List<T> items) where T : NumericType { }

看起来完全像您可能想要的,但是这里有个问题, 返回类型是什么? 假设列表包含doubleintbyte等,每个列表在与某些其他类型相乘,相加,除等后均具有加宽转换,因此编译器很难知道返回的类型。

如果允许我们做类似的事情,那将是同样的问题:

public T SomeMethod<T>(List<T> items) where T : in(int, double, float) { }

一个int * int == int ,但是int * double == double ,或更糟糕的是, double / int == int ,正如您所看到的, T不能被推断,这会破坏语言中的其他构造,例如:

var mySum = SomeMethod(myNumericList);

由于var是在编译时隐式键入的,因此它无法确定适当的类型,因此无法编译该语句。

您可以做的最好的事情就是重载函数,这样您的原型就变成了:

public int SomeMethod(IEnumerable<int> items) { }
public double SomeMethod(IEnumerable<double> items) { }
public float SomeMethod(IEnumerable<float> items) { }

或者,另一方面,您可以坚持通用约束并执行以下操作:

public void MyMethod<U, T>(U items) where U : List<T>
{
    if (typeof(T) is int) { ((List<int>)items).Sum() }
    if (typeof(T) is double) { ((List<double>)items).Sum() }
    //Repeat for the remaining numeric types.
}

或者,正如DavidG的答案所指出的,请使用选择器功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM