【问题标题】:Implementing twice the same generic interface, with type argument constraints使用类型参数约束实现两次相同的通用接口
【发布时间】:2013-04-04 07:22:11
【问题描述】:

拥有

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&lt;String, String&gt; instance; 会导致两个接口实现的歧义。但是为什么这是不可能的

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

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

编辑
Why does this result in CS0695 中的“Soner Gönül”提出了一个解决方法,使用两个级别的类继承,如下所示:

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"

【问题讨论】:

标签: c# generics interface constraints


【解决方案1】:

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

是的,它们可以是同一个类。约束不能是 sealed classes1 所以 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:

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

【讨论】:

  • 感谢您的回答。我的观点是Student 和Teacher 不 相互继承。但正如其他人回答的那样,这没关系,因为没有考虑类型约束。
  • 约束不能被密封类是合乎逻辑的。密封修饰符防止其他类从它继承。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-07
  • 2011-01-13
相关资源
最近更新 更多