C# 在Lazy中强制转换接口类型<;T>;

C# 在Lazy中强制转换接口类型<;T>;,c#,generics,C#,Generics,我想要这样的东西: public interface IAnimal { } public class Dog : IAnimal { public Dog() {} } public class Cat : IAnimal { public Cat() {} } public abstract class TestClassBase { public TestClassBase() { _lazyAnimal = CreateLazyAni

我想要这样的东西:

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
    }
}
公共接口IAnimal
{ }
公家犬:IAnimal
{
公犬(){}
}
公共类Cat:IAnimal
{
公共猫(){}
}
公共抽象类TestClassBase
{
公共TestClassBase()
{
_lazyAnimal=创建lazyAnimal();
}
私人懒惰动物=null;
公共动物
{
得到
{ 
i活体动物=null;
如果(_lazyamal!=null)
动物=_lazyamal.Value;
返回动物;
}
}
//可以覆盖以支持其他动物
公共虚拟懒人CreateLazyAnimal()
{
//默认的动物是狗
return new Lazy();//这种类型的转换不起作用,我不知道有什么好的工作环境
}
}
通过修补MEF,我知道它能够找到不同的类型并将其存储到Lazy中,实现了一个接口。只是不知道自己该怎么做。

不允许将
惰性
转换为
惰性
,因为类型不同(惰性类型仅从
对象继承)。在某些情况下,强制转换是有意义的-例如将
IEnumerable
强制转换为
IEnumerable
,但强制转换并非在所有情况下都是安全的

C#4.0在安全案例中增加了对该转换的支持。它被称为协方差和逆变。比如这个

不幸的是,在C#4.0中,这只适用于接口和委托,而不适用于具体类(例如,
Lazy
)。您可能可以通过创建接口
ILazy
和标准
Lazy
类型的包装器来解决这个问题,但是只编写从
Lazy
Lazy
的转换可能更容易些
Lazy
不能直接转换为
Lazy
,但是由于
Dog
可以转换为
IAnimal
,因此可以使用
Lazy
,它需要
IAnimal
(严格来说,它需要一个返回
IAnimal
)的Func,并提供一个
Dog

    public virtual Lazy<IAnimal> CreateLazyAnimal()
    {
        // default animal is a dog
        return new Lazy<IAnimal>(() => new Dog());
    }
public虚拟动物()
{
//默认的动物是狗
返回新的Lazy(()=>newdog());
}

无需编写从
惰性
惰性
的转换;只需显式地使用
new Lazy(()=>new Dog())
(而不是让
new Lazy()
自动使用默认构造函数)。我对协方差和逆变都是新手,这些概念一开始似乎有点令人困惑。据我所知,把懒惰定义为懒惰不是更有意义吗?@mbursill:是的,它(原则上)是这样的。问题是,您只能对接口使用
out
修饰符,而不能对类使用(一般来说,这对类的工作方式还不太清楚)。