简体   繁体   English

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

[英]Covariant use of generic Lazy class in C#

Assuming that this applies: 假设这适用:

public class Cat : Animal { }

and assuming that I have a method: 并假设我有一个方法:

public void Feed(Animal animal) { ... }

And I can call it this way: 我可以这样称呼它:

var animal = new Cat();
Feed(animal);

How can I get this working when Feed is refactored to only support Lazy<Animal> as parameter? Feed被重构为仅支持Lazy<Animal>作为参数时,如何才能使其工作? I'd like to pass in my var lazyAnimal = new Lazy<Cat>(); 我想传入我的var lazyAnimal = new Lazy<Cat>(); somehow. 不知何故。

This obviously doesnt work: 这显然不起作用:

var lazyAnimal = new Lazy<Cat>();
Feed(lazyAnimal);

You can't, basically - not directly, anyway. 你不能,基本上 - 不管是直接的。 Lazy<T> is a class, so doesn't suppose generic variance. Lazy<T>是一个类,所以不要假设泛型方差。

You could create your own ILazy<out T> interface, implement it using Lazy<T> , and then make Feed take ILazy<Animal> instead. 可以创建自己的ILazy<out T>界面, 使用 Lazy<T>实现它,然后使Feed改为使用ILazy<Animal> The implementation would be trivial. 实施将是微不足道的。

Alternatively, you could make Feed generic: 或者,您可以使Feed通用:

public void Feed<T>(Lazy<T> animal) where T : Animal

Or Servy's suggestion of taking Func<Animal> would work too, and you could call it using a lambda expression for the Lazy<T> : 或者Servy关于服用Func<Animal>的建议也会起作用,你可以使用lambda表达式为Lazy<T>调用它:

Feed(() => lazyAnimal.Value);

Well, you won't be able to use it exactly as is. 好吧,你将无法完全按原样使用它。 Probably the simplest refactor would be to have it accept a Func<Animal> instead of a Lazy . 可能最简单的重构就是让它接受一个Func<Animal>而不是一个Lazy Then you could pass in a lambda that fetches the value of a Lazy . 然后你可以传入一个获取Lazy值的lambda。 Func is covariant with respect to it's return type. Func对于它的返回类型是协变的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM