Ответ 1
Lazy<Dog>
не может быть преобразован непосредственно в Lazy<IAnimal>
, но поскольку Dog
можно преобразовать в IAnimal
, вы можете использовать конструктор Lazy<IAnimal>
Мне нужно что-то вроде этого:
public interface IAnimal
{ }
public class Dog : IAnimal
{
public Dog() {}
}
public class Cat : IAnimal
{
public Cat() {}
}
public abstract class TestClassBase
{
public TestClassBase()
{
_lazyAnimal = CreateLazyAnimal();
}
private Lazy<IAnimal> _lazyAnimal = null;
public IAnimal Animal
{
get
{
IAnimal animal = null;
if (_lazyAnimal != null)
animal = _lazyAnimal.Value;
return animal;
}
}
// Could be overridden to support other animals
public virtual Lazy<IAnimal> CreateLazyAnimal()
{
// default animal is a dog
return new Lazy<Dog>(); // this type of casting doesn't work and I don't know a good workground
}
}
Я знаю, что с помощью MEF мне удается найти и хранить разные типы, реализующие один интерфейс, в Lazy <T> . Просто не уверен, как это сделать сам.
Lazy<Dog>
не может быть преобразован непосредственно в Lazy<IAnimal>
, но поскольку Dog
можно преобразовать в IAnimal
, вы можете использовать конструктор Lazy<IAnimal>
Отбрасывание Lazy<Dog>
в Lazy<IAnimal>
не допускается, поскольку типы различны (тип Lazy<T>
наследуется только от object
). В некоторых случаях литье может иметь смысл - например, отбрасывание IEnuerable<Dog>
до IEnumerable<IAnimal>
, но литье не является безопасным во всех случаях.
С# 4.0 добавляет поддержку для этого литья в безопасном случае. Это называется ковариацией и контравариантностью. Например, эта статья дает хороший обзор.
К сожалению, в С# 4.0 это работает только для интерфейсов и делегатов, а не для конкретных классов (например, Lazy<T>
). Вероятно, вы решили проблему, создав интерфейс ILazy<out T>
и оболочку для стандартного типа Lazy
, но, вероятно, проще просто написать преобразование с Lazy<Dog>
на Lazy<IAnimal>
.