2013-04-04 99 views
3

实施两次相同的通用接口,具有类型参数的约束

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不能是同一类? (编译器误差是相同的情况下,而不类型约束)

编辑
“Soner格尼尔”在Why does this result in CS0695提出了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

参见:[?为何C#编译器抱怨“类型可以结合”,当它们从不同的基类派生](http://stackoverflow.com/questions/7664790/why-does-the -c-sharp-compiler-complain-that-types-may-unify-when-they-derive-f),它非常相似。 – Ani 2013-04-04 07:30:15

+1

通过搜索CS0695找到[此问题](http://stackoverflow.com/questions/15316898/why-does-this-result-in-cs0695)。答案包括规范参考,包括:“在确定所有可能的构造类型时,不考虑约束声明。” – 2013-04-04 07:34:35

+0

@Ani谢谢,现在我明白,这是不可能的定义的C#。这可能也是VB的情况。 – Karuzo 2013-04-04 08:19:29

回答

1

为T1和T2不能成为同一班?

是的,他们可以是同一个班级。约束不能是sealed类因此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

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

+0

谢谢你的回答。我的观点是“学生”和“老师”不会互相继承。但正如其他人回答的那样,这并不重要,因为不考虑类型限制。 – Karuzo 2013-04-04 08:34:19

+1

约束不能被密封的类是合乎逻辑的。密封修饰符可防止其他类从其继承。 – 2013-04-04 08:38:25

相关问题