简体   繁体   中英

Implementing twice the same generic interface, with type argument constraints

Having

public interface IGeneric<T>{}

public class Student{}

public class Teacher{}

this is possible

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

this is not possible

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

because GenericClass<String, String> instance; would cause ambiguity for the two interface implementation. But why this is not possible

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

as T1 and T2 cannot be of the same class? (The compiler error is the same as in the case without type constrains)

Edit
"Soner Gönül" in Why does this result in CS0695 proposed a workarround, using two levels of class inheritance, like this:

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"; } } }

Code like this then produce expected result

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"

as T1 and T2 cannot be of the same class?

Yes, they can be the same class. Constraints cannot be sealed classes 1 so Teacher can be derived from Student or vise versa. It's not logical but compiler has no idea about it.

For example,

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>();
    }
}

will compile without any problem. Demo


  1. Docs :

    Constraints can also be class types, such as abstract base classes. However, constraints cannot be value types or sealed classes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM