Внедрение интерфейса с общим ограничением
Бит удивил, почему это не работает.
Является ли это ограничением компилятора или имеет смысл не поддерживать его?
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; }
}