使用类型参数约束实现两次相同的通用接口

时间:2013-04-04 07:22:12

标签: c# generics interface constraints

具有

public interface IGeneric<T>{}

public class Student{}

public class Teacher{}

这是可能的

public class ConcreateClass : IGeneric<Student>, IGeneric<Teacher>{}

这是不可能的

public class GenericClass<T1, T2> : IGeneric<T1>, IGeneric<T2> {}

因为GenericClass<String, String> instance;会导致两个接口实现的歧义。但为什么这是不可能的

public class GenericClassWithTypeConstraints<T1, T2> : IGeneric<T1>, IGeneric<T2>
    where T1 : Student
    where T2 : Teacher
{}

因为T1和T2不能属于同一类? (编译器错误与没有类型约束的情况相同)

修改
Why does this result in CS0695中的“SonerGönül”提出了一个使用两个级别的类继承的workarround,如下所示:

public interface IGeneric<T> { String Name { get; } }

public class Student{}

public class Teacher{}

public class GenericClassBase<T1> : IGeneric<T1>
    where T1 : Student
{ String IGeneric<T1>.Name { get { return "Generic class of Student"; } } }

public class GenericClassDerived<T1, T2> : GenericClassBase<T1>, IGeneric<T2>
    where T1 : Student
    where T2 : Teacher
{ String IGeneric<T2>.Name { get { return "Generic class of Teacher"; } } }

这样的代码然后产生预期的结果

GenericClassDerived<Student, Teacher> X = new GenericClassDerived<Student, Teacher>();
Console.WriteLine(((IGeneric<Student>)X).Name); //outputs "Generic class of Student"
Console.WriteLine(((IGeneric<Teacher>)X).Name); //outputs "Generic class of Teacher"

1 个答案:

答案 0 :(得分:1)

  

因为T1和T2不能属于同一类?

是的,他们可以是同一个班级。约束不能是sealed 1 ,因此Teacher可以从Student派生,反之亦然。这不符合逻辑,但编译器对此一无所知。

例如,

using System;

public class Student{}

public class Teacher : Student{}

public class GenericClassWithTypeConstraints<T1, T2>
    where T1 : Student
    where T2 : Teacher
{}

class Test {
    static void Main() {
        var obj = new GenericClassWithTypeConstraints<Teacher, Teacher>();
    }
}

将编译没有任何问题。 Demo


  1.   

    Docs

         

    约束也可以是类类型,例如抽象基类。   但是,约束不能是值类型或密封类。