在C#中协变使用泛型Lazy类

thm*_*shd 4 c# covariance lazy-initialization c#-4.0

假设这适用:

public class Cat : Animal { }
Run Code Online (Sandbox Code Playgroud)

并假设我有一个方法:

public void Feed(Animal animal) { ... }
Run Code Online (Sandbox Code Playgroud)

我可以这样称呼它:

var animal = new Cat();
Feed(animal);
Run Code Online (Sandbox Code Playgroud)

Feed重构为仅支持Lazy<Animal>参数时,如何才能使其正常工作?我想以var lazyAnimal = new Lazy<Cat>();某种方式传递给我.

这显然不起作用:

var lazyAnimal = new Lazy<Cat>();
Feed(lazyAnimal);
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 12

你不能,基本上 - 不管是直接的.Lazy<T>是一个类,所以不要假设泛型方差.

可以创建自己的ILazy<out T>接口,实现它 Lazy<T>,然后进行FeedILazy<Animal>来代替.实施将是微不足道的.

或者,您可以制作Feed通用:

public void Feed<T>(Lazy<T> animal) where T : Animal
Run Code Online (Sandbox Code Playgroud)

或者Servy的建议Func<Animal>也可以使用,你可以使用lambda表达式来调用它Lazy<T>:

Feed(() => lazyAnimal.Value);
Run Code Online (Sandbox Code Playgroud)


Ser*_*rvy 7

好吧,你将无法完全按原样使用它.可能最简单的重构就是让它接受Func<Animal>而不是a Lazy.然后你可以传入一个获取a值的lambda Lazy. Func对于它的返回类型是协变的.