C#泛型:CS0311在实现符合通用接口契约的泛型类时

时间:2013-09-07 11:44:39

标签: c# generics interface

我已经四处寻找并找到了一个有点相关的答案但是,对于我的生活,我仍然无法弄清楚我哪里出错了!我正在尝试使用类似于下面的代码来实现一些通用类型的树数据结构,但是我得到了编译器错误CS0311。

  

错误CS0311:类型'Test.TestType'不能用作泛型类型或方法'Test.TreeIndex< K>'中的类型参数'K'。没有从'Test.TestType'到'Test.IIndexable< Test.TestType>'的隐式引用转换。

我只是无法弄清楚为什么编译器不知道如何处理这个问题,所以任何线索都会非常感激。

public interface IIndexable<K> where K : IComparable
{
    byte[] ToBytes();
    K FromBytes(byte[] bytes);
}

public class TestType : IIndexable<byte>, IComparable
{
    public int CompareTo(object b)
    {
        return 1;
    }

    public byte[] ToBytes()
    {
        return new byte[1];
    }

    public byte FromBytes(byte[] bytes)
    {
        return 0;
    }
}

public class TreeIndex<K> where K : IComparable, IIndexable<K>
{
    public int SomeMethod(K a, K b)
    {
        return a.CompareTo(b);
    }
}

class Program
{
    static void Main()
    {
        TreeIndex<TestType> treeIndex = new TreeIndex<TestType>(); // CS0311 generated twice here
    }
}

4 个答案:

答案 0 :(得分:3)

您的TreeIndex<K>课程要求K实施IIndexable<K>,因此TestType应实施IIndexable<TestType>而不是IIndexable<byte>

public class TestType : IIndexable<TestType>, IComparable
{
    public int CompareTo(object b)
    {
        return 1;
    }

    public byte[] ToBytes()
    {
        return new byte[1];
    }

    public TestType FromBytes(byte[] bytes)
    {
        //...
    }
}

您可能还想考虑在IComparable<T>接口上使用通用IIndexable<K>约束,即

public interface IIndexable<K> where K : IComparable<K>
{
    byte[] ToBytes();
    K FromBytes(byte[] bytes);
}

答案 1 :(得分:0)

由于您具有以下通用约束

public class TreeIndex<K> where K : IComparable, IIndexable<K>

你在宣布 TreeIndex<TestType>

你说TestType实现IIndexable<TestType>,这不可能是真的。

答案 2 :(得分:0)

您告诉编译器制作new TreeIndex<TestType>()

TreeIndex的定义是TreeIndex<K> where K : IComparable, IIndexable<K>,这意味着您为通用传递的类型必须是IIndexable<K>

所以当你说:TreeIndex<TestType>时,编译器希望TestType的类型为IIndexable<K>,其中KTestType,所以它期望{{} 1}}实现TestType,但它不实现。它实现了IIndexable<TestType>


很难说出你的案例最佳解决方案是什么,但解决它的一种方法是指定2个泛型:

IIndexable<byte>

答案 3 :(得分:0)

来自Compiler Error CS0311

  

当约束应用于泛型类型参数时,隐式   身份或参考转换必须存在于具体参数中   到约束的类型。纠正此错误

     

更改您用于创建类的参数。

     
      
  • 更改您用于创建班级的参数。
  •   
  • 如果您拥有该类,则可以删除该约束,或者执行某些操作以启用隐式引用或标识转换。对于   例如,您可以使第二种类型继承自第一种
  •   

基于此,TreeIndex<K>课程必须实施IIndexable<TestType>而不是IIndexable<byte>

当您编写TreeIndex<TestType>编译器要求IIndexable<K>时,IIndexable<TestType>表示您的案例。

但是您的TestType课程没有实施IIndexable<TestType>。它实现了IIndexable<byte>