我想要这样的东西:
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
}
}
Run Code Online (Sandbox Code Playgroud)
我知道,通过修改MEF,它设法在Lazy <T>中找到并存储不同类型,实现单个接口.只是不知道如何自己做.
Bra*_*ger 18
Lazy<Dog>
不能直接转换为Lazy<IAnimal>
,但既然Dog
可以转换为IAnimal
你可以使用期望的Lazy<IAnimal>
构造函数重载IAnimal
(严格来说,它需要一个Func返回一个IAnimal
)并提供一个Dog
代替:
public virtual Lazy<IAnimal> CreateLazyAnimal()
{
// default animal is a dog
return new Lazy<IAnimal>(() => new Dog());
}
Run Code Online (Sandbox Code Playgroud)
不允许转换Lazy<Dog>
为Lazy<IAnimal>
因为类型不同(Lazy<T>
类型仅从中继承object
).在某些情况下,可以铸造有意义的-例如铸造IEnuerable<Dog>
到IEnumerable<IAnimal>
,但铸造是不是在所有情况下的安全.
C#4.0在安全案例中增加了对此转换的支持.它被称为协方差和逆变.例如,本文给出了一个很好的概述.
不幸的是,在C#4.0中,这仅适用于接口和委托,而不适用于具体类(例如Lazy<T>
).您可以通过创建界面可能解决问题ILazy<out T>
和标准的包装Lazy
类型,但它可能是更容易刚刚从写转换Lazy<Dog>
到Lazy<IAnimal>
.