我已经创建了一个模板,它返回数组中最大值的索引。它可以工作,但前提是我传入了一个奇怪的类型列表。
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;
}现在使用它:
List<IComparable<Double>> arr = new List<IComparable<Double>>(); // THIS WORKS
List<Double> arr = new List<Double>(); // THIS DOESN'T后面的列表是我想要使用的,它给出了这个编译器错误:
cannot convert from 'System.Collections.Generic.List<double>' to 'System.Collections.Generic.IEnumerable<System.IComparable<double>>'这怎么可能呢?“IComparable”是一个Double;取自它的定义:
public struct Double : IComparable, IFormattable, IConvertible, IComparable<Double>, IEquatable<Double>
发布于 2017-05-15 23:03:32
我认为其他的答案已经解决了为什么你的代码写成isn't working the way you'd expect,甚至为什么code will fail in some cases。然而,没有一个答案告诉你做你想做的事情的方法:
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;
}
}因此,我在这里引入了一个通用约束( where T : IComparable<T>)。这告诉编译器,无论T是什么,它都将实现IComparable<T>。
另外,我将枚举器放在一个using语句中,这将保证它的Dispose方法被调用。
无论如何,现在当你调用这个方法时,它将直接作用于IEnumerable<double>,甚至会为你推导出类型参数:
var someDoubles = new List<double> { 3, 2, 1 };
Console.WriteLine( FindMaxIndex( someDoubles ) ) // Prints "0";此外,如果在static类中声明了FindMaxIndex,则可以将this关键字放在源参数前面,使其成为扩展方法:
public static int FindMaxIndex<T>( this IEnumerable<T> source ) where T : IComparable<T>
{
// ...
}现在你可以这样调用它:
list.FindMaxIndex()发布于 2017-05-15 21:48:18
泛型协方差仅在泛型参数为引用类型时有效。因为您有一个值类型作为参数,所以它不能执行任何协变转换。
发布于 2017-05-15 21:49:28
double是IComparable<double>,但List<double>不是List<IComparable<double>>。
它也不能被允许。考虑一下:
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?On可以在接口中包含差异,因此可以将List<string>传递给IEnumerable<object>,但只有当差异中涉及的类型都是引用类型时,才会发生这种情况。
https://stackoverflow.com/questions/43981095
复制相似问题