Этот вопрос был в течение некоторого времени в разных формах, но мне не удалось найти хорошее объяснение.
Итак, в C #, давайте рассмотрим, у меня есть интерфейс:
interface ITest<T>
{
}
И тогда у меня есть класс, реализующий его:
class TestClass<T> : ITest<T>
{
}
Теперь, если я создам метод со следующей сигнатурой:
void TestMethod<T>(TestClass<ITest<T>> tt)
{
}
И попробую вызвать его со следующим аргументом:
...
var testParam = new TestClass<TestClass<int>>();
TestMethod(testParam);
...
Дает ошибку типа «не удалось преобразовать» во время компиляции.Хотя класс, реализующий интерфейс, должен быть совместим по присваиванию с самим типом интерфейса.(Я не принимаю во внимание дисперсию здесь, потому что в рассматриваемом примере класс имеет тот же аргумент типа, что и интерфейс).
Конечно, я могу немного обмануть и сделать следующее:
void TestMethod<TVariant, TInterface>(TestClass<TInterface> tt)
where TInterface : ITest<TVariant>
{
}
....
....
var testParam = new TestClass<TestClass<int>>();
TestMethod<int, TestClass<int>>(testParam);
...
Ноэто убивает вывод параметров типа (то есть вы не можете удалить (int, TestClass (int)) из вызова метода), и код становится довольно замусоренным с явными спецификациями аргументов типа.
Итак, у меня есть 2 вопроса:
- Можно ли что-нибудь сделать, чтобы преодолеть такую проблему?Я имею в виду, использовать типы, реализующие интерфейсы, в качестве аргументов типа, где ожидаются универсальные интерфейсы в качестве аргументов типа?
- Что здесь происходит?Какова точная причина такого ограничения времени компиляции?Это просто техническая сдержанность или есть какие-то предостережения с поведением, которые я хочу реализовать?