Внедрение интерфейса с общим ограничением

Бит удивил, почему это не работает.

Является ли это ограничением компилятора или имеет смысл не поддерживать его?

public class Class1<T> : IInterface
    where T : Test2
{
    public T Test { get; private set; }
}

public class Test2
{
}

internal interface IInterface
{
    Test2 Test { get; }
}

Ошибка, которую я получаю,

'ClassLibrary1.Class1<T>' does not implement interface member 'ClassLibrary1.IInterface.Test'. 
'ClassLibrary1.Class1<T>.Test' cannot implement 'ClassLibrary1.IInterface.Test' because it does not have the matching return type of 'ClassLibrary1.Test2'.

Ответ 1

Для большей коррекции, реализуйте интерфейс явно:

public class Class1<T> : IInterface
where T : Test2
{
    public T Test { get; private set; }

    Test2 IInterface.Test
    {
        get { ... }
    }
}

Затем вы можете избежать скомпилированной ошибки.

Ответ 2

Так как T может быть любым типом, производным от Test2, Class1 точно не реализует IInterface.

В более общем смысле, невозможно реализовать интерфейс, возвращая ковариантный тип:

interface IFoo
{
    object Bar { get; }
}

class Broken : IFoo
{
    string Bar { get; } // you cannot expect to implement IFoo this way!
}

Ответ 3

Измените свой интерфейс на это, и он скомпилирует:

public class Class1<T> : IInterface<T>
    where T : Test2
{
    public T Test { get; private set; }
}

public class Test2
{
}

internal interface IInterface<T>
    where T : Test2
{
    T Test { get; }
}

Ответ 4

Возможно ли, чтобы вы создали свой общий интерфейс, например.

public class Class1<T> : IInterface<T>
    where T : Test2
{ 
    public T Test { get; private set; } 
} 

public class Test2 
{ 
} 

internal interface IInterface<T>
{ 
    T Test { get; } 
} 

Или вы пытаетесь избежать дженериков на интерфейсе (есть и веские причины для этого!)

Ответ 5

Интерфейс говорит, что свойство Test имеет тип Test2. В вашей реализации Свойство Class1 Test имеет класс, унаследованный от Test2, но не совсем тот. Чтобы сделать то, что вы хотите, вам нужно написать что-то вроде этого:

public class Class1<T> : IInterface
    where T : Test2
{
    private T _test;
    public Test2 Test { get{return _test} }
}

public class Test2
{ 
}

internal interface IInterface 
{
    Test2 Test { get; }
}