2016-03-15 3 views
0

Возможно ли вернуть производный класс в определение интерфейса в C#? Некоторая ковариация типа возврата.Возврат производного класса вместо интерфейса

Например:

public interface IAnimal 
{ 
    this GetAnimal(); 
} 

public class Dog : IAnimal 
{ 
    Dog GetAnimal() { return new Dog(); } 
} 
+0

Простой ответ: «вы не можете». –

ответ

1

C# не поддерживает тип возвращаемого ковариации, по крайней мере, в C# 6. Это very commonly requested feature на Рослин GitHub, и задолго до того, как Рослин даже существовала.

Эрик Липперт написал в своем answer:

Функция не реализована, потому что здесь никто никогда не реализовали. Необходимым, но недостаточным требованием является то, что преимущества функции превышают ее затраты.

Расходы значительны. Функция не поддерживается из-за среды выполнения, она напрямую работает против нашей цели сделать C# версией, потому что она представляет еще одну форму проблемы хрупкого базового класса.

Итак, откиньтесь на спинку сиденья, прижмитесь и скрестите пальцы на C# 7/8/9. Но не слишком сильно рассчитывайте на свои надежды - как сказано, это недорогая низкоэффективная функция, которая, скорее всего, потребует изменений в CLR.

На данный момент взгляните на Christos' answer.

2

Можно ли вернуть производный класс в определении интерфейса в C#?

Да, если вы определяете общий интерфейс.

public interface IAnimal<T> 
{ 
    T GetAnimal(); 
} 

public class Dog : IAnimal<Dog> 
{ 
    public Dog GetAnimal() { return new Dog(); } 
} 

Вы можете прочитать далее об этом here.

+0

Я уверен, что это не то, что ожидает OP. –

+0

@ ЭльдарДорджиев. Вы правы. Я только что исправил соответствующий ответ. Спасибо – Christos

+0

У меня была такая же идея, но хорошо, это не так чисто, как хотелось бы. Это действительно упрощенный пример, который становится очень сложным в реальном использовании: / – Nicolas

1

Конечно, если вы передаете производный класс как тип ограничения :)

public interface IAnimal<T> 
{ 
    T GetAnimal(); 
} 

public class Dog : IAnimal<Dog> 
{ 
    public Dog GetAnimal() { return new Dog(); } 
}