Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从实现IComparable的东西继承时,C#BinarySearch会中断<;T>;?_C#_Generics_Inheritance_Sorting_Interface - Fatal编程技术网

从实现IComparable的东西继承时,C#BinarySearch会中断<;T>;?

从实现IComparable的东西继承时,C#BinarySearch会中断<;T>;?,c#,generics,inheritance,sorting,interface,C#,Generics,Inheritance,Sorting,Interface,在.NET中,如果您试图搜索的项继承自IComparable,而不是直接实现它,则BinarySearch算法(在列表、数组等中)似乎会失败: List<B> foo = new List<B>(); // B inherits from A, which implements IComparable<A> foo.Add(new B()); foo.BinarySearch(new B()); // InvalidOperationException,

在.NET中,如果您试图搜索的项继承自IComparable,而不是直接实现它,则BinarySearch算法(在列表、数组等中)似乎会失败:

List<B> foo = new List<B>(); // B inherits from A, which implements IComparable<A>
foo.Add(new B());
foo.BinarySearch(new B());   // InvalidOperationException, "Failed to compare two elements in the array."
List foo=new List();//B继承自A,后者实现了IComparable
foo.Add(新的B());
foo.BinarySearch(新的B());//InvalidOperationException,“无法比较数组中的两个元素。”
其中:

public abstract class A : IComparable<A>
{
    public int x;

    public int CompareTo(A other)
    {
        return x.CompareTo(other.x);
    }
}

public class B : A {}
公共抽象类A:IComparable
{
公共int x;
公共整数比较(A其他)
{
返回x.CompareTo(其他x);
}
}
公共B类:A{}

有办法解决这个问题吗?在B类中实现CompareTo(B-other)似乎不起作用。

文档非常清楚地说明了这一点:

检查类型T是否实现IComparable泛型接口并使用该实现(如果可用)。如果不是,Comparer.Default将检查类型T是否实现IComparable接口。如果类型T未实现任何一个接口,则Comparer.Default会抛出InvalidOperationException

因此,一个简单的解决方案是实现非通用接口
IComparable

CompareTo(B other)
添加到(B other)将对您有效,只要您还实现了
IComparable
——您可能忘记了这一点


一个有趣的解决方案是使用C#4编译代码,它在C#4中运行时没有任何错误。C#4引入了通用协方差:
public interface IComparable
vs
public interface IComparable
,并且发布的代码按预期工作。

对,所以问题是它试图看看
类B
是否实现了
IComparable
,但它没有实现,因为它实际上实现了
IComparable
,然后尝试
IComparable
,然后放弃。正如Kobi指出的,实现非泛型的IComparable将解决这个问题。

尽管上述答案对于4.0之前的.net版本是正确的,但值得注意的是.net 4.0对IComparable的定义是协变的,这意味着如果类实现IComparable,但没有显式实现IComparable,if IComparable的实现将被视为if IComparable的实现

请注意,这不适用于IEquatable,但由于派生类型无论如何都不应该实现IEquatable,所以这不应该是一个问题


还请注意,与逻辑上绑定为实现与Object.Equals非常相似的语义的IEquatable不同(因为GetHashCode实现返回的对象必须比较不相等),在许多情况下,IComparable应该逻辑上返回相等,即使IComparable应该比较不相等(在这种情况下,派生类型通常应实现IComparable,但不应实现重新实现IComparable。请注意,如果IComparable.Compare返回零,则这并不意味着对象相等,而只是意味着两个对象的排名都不高于另一个。

此代码在我的C#compiler@Stewart-你可能正在使用g C#4。@Kobi-哎呀,完全正确。我忘了这已经改变了,问题没有提到版本。