3

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"
Community
  • 1
  • 1
Karuzo
  • 31
  • 1
  • 4
  • 1
    See: [Why does the C# compiler complain that “types may unify” when they derive from different base classes?](http://stackoverflow.com/questions/7664790/why-does-the-c-sharp-compiler-complain-that-types-may-unify-when-they-derive-f), which is very similar. – Ani Apr 04 '13 at 07:30
  • 1
    Found [this question](http://stackoverflow.com/questions/15316898/why-does-this-result-in-cs0695) by searching on CS0695. The answer includes spec references including: "Constraint declarations are not considered when determining all possible constructed types." – Damien_The_Unbeliever Apr 04 '13 at 07:34
  • @Ani Thanks, now I understand that this is not possible by definition of C#. This is probably the case also for VB. – Karuzo Apr 04 '13 at 08:19
  • @Damien_The_UnbelieverThanks. In your link I have found a contribution of Soner Gönül, that is a sort of workarround, I will place it to my original answer. – Karuzo Apr 04 '13 at 08:21
  • possible duplicate of [How to use same interface two times with diferrent template parameters, in an interface?](http://stackoverflow.com/questions/1287010/how-to-use-same-interface-two-times-with-diferrent-template-parameters-in-an-in) – nawfal May 25 '13 at 09:13

1 Answers1

1

as T1 and T2 cannot be of the same class?

Yes, they can be the same class. Constraints cannot be sealed classes1 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.

Leri
  • 12,367
  • 7
  • 43
  • 60
  • Thanks for you answer. My point was that `Student` and `Teacher` __doesn't__ inherits from each other. But as others answered, it doesn't matter, because type constraints are not considered. – Karuzo Apr 04 '13 at 08:34
  • 1
    Constraints cannot be sealed classes is logical. The sealed modifier prevents other classes from inheriting from it. – Ken Kin Apr 04 '13 at 08:38