C# &引用;“双”字;不';t被选为“演员”;i可比较<;双倍>&引用;
我创建了一个模板,它返回数组中最大值的索引。这是可行的,但前提是我通过了一个奇怪的演员名单C# &引用;“双”字;不';t被选为“演员”;i可比较<;双倍>&引用;,c#,generics,covariance,C#,Generics,Covariance,我创建了一个模板,它返回数组中最大值的索引。这是可行的,但前提是我通过了一个奇怪的演员名单 static public int FindMaxIndex<T>( IEnumerable<IComparable<T>> arr ) { IEnumerator<IComparable<T>> it = arr.GetEnumerator(); if (!it.MoveNext()) retur
static public int FindMaxIndex<T>( IEnumerable<IComparable<T>> arr )
{
IEnumerator<IComparable<T>> it = arr.GetEnumerator();
if (!it.MoveNext()) return -1;
int index = 1, maxIndex = 0;
IComparable<T> max = it.Current;
while (it.MoveNext())
{
if (max.CompareTo( (T)(it.Current) ) < 0)
{
maxIndex = index;
max = it.Current;
}
++index;
}
return maxIndex;
}
静态公共int FindMaxIndex(IEnumerable arr)
{
IEnumerator it=arr.GetEnumerator();
如果(!it.MoveNext())返回-1;
int-index=1,maxIndex=0;
i可比较最大值=it.电流;
while(it.MoveNext())
{
如果(最大比较值((T)(it.Current))<0)
{
maxIndex=索引;
最大值=it.电流;
}
++指数;
}
返回最大索引;
}
现在使用它:
List<IComparable<Double>> arr = new List<IComparable<Double>>(); // THIS WORKS
List<Double> arr = new List<Double>(); // THIS DOESN'T
List arr=new List();//这很有效
List arr=新列表();//这并不重要
后面的列表是我要使用的,它给出了以下编译器错误:
cannot convert from 'System.Collections.Generic.List<double>' to 'System.Collections.Generic.IEnumerable<System.IComparable<double>>'
无法从“System.Collections.Generic.List”转换为“System.Collections.Generic.IEnumerable”
这怎么可能?“Double”是一个不可比较的词;根据其定义:
public struct Double:IComparable、ifformattable、IConvertible、IComparable、IEquatable
泛型协方差仅在泛型参数为引用类型时有效。因为您有一个值类型作为参数,所以它不能执行任何协变转换。double
是一个i可比较的
,但List
不是一个列表
也不能允许这样做。考虑:
private class ScrewItUp : IComparable<double>
{
public int CompareTo(double value) => 0;
}
List<IComparable<double>> list = new List<double>(); // you propose that this work.
list.Add(new ScrewItUp()); // What's this supposed to do, then?
private-class-ScrewItUp:i可比较
{
公共整数比较(双值)=>0;
}
列表=新列表();//你建议这项工作。
list.Add(新的ScrewItUp());//那这是怎么回事?
On可以在接口中包含差异,例如,List
可以传递给IEnumerable
,但只有当差异中包含的类型都是引用类型时,才会发生这种情况。方向正确。下面的代码起作用
double
可能是一个i可比较的
。但是列表
不是列表
。需要强制转换列表中的每个元素。您不能强制转换整个列表
List<double> list = new List<double>() { 1,5,3};
Console.WriteLine(FindMaxIndex(list.Cast<IComparable<double>>()));
List List=newlist(){1,5,3};
Console.WriteLine(FindMaxIndex(list.Cast());
我认为其他的答案已经说明了为什么你的代码是这样写的,甚至为什么会这样。但是,没有一个答案能告诉你如何做你想做的事情:
public static int FindMaxIndex<T>( IEnumerable<T> source ) where T : IComparable<T>
{
using( var e = source.GetEnumerator() )
{
if( !e.MoveNext() ) return -1;
T maxValue = e.Current;
int maxIndex = 0;
for( int i = 1; e.MoveNext(); ++i )
{
if( maxValue.CompareTo( e.Current ) < 0 )
{
maxIndex = i;
maxValue = e.Current;
}
}
return maxIndex;
}
}
此外,如果在静态
类中声明了FindMaxIndex
,则可以将this
关键字放在源参数前面,使其成为扩展方法:
public static int FindMaxIndex<T>( this IEnumerable<T> source ) where T : IComparable<T>
{
// ...
}
如果您使用引用类型而不是
double
,问题代码将失败,同样的方法。@Evk当double
是一个类时,它在我的机器上编译得很好。我的坏,是我方面的一个问题。不相关但。。。这就是为什么我更喜欢C++:- OP正在执行转换为public static int FindMaxIndex<T>( this IEnumerable<T> source ) where T : IComparable<T>
{
// ...
}
list.FindMaxIndex()