我正在阅读 this msdn article ,逆变示例(键盘和鼠标事件)很好用,而协变示例(哺乳动物和狗)看起来不是这样。
键盘和鼠标事件很棒,因为您可以在多种情况下使用 1 个处理程序;但是我想不出将返回更多派生类型的处理程序分配给返回基类型的处理程序有什么好处,更不用说拥有一个关心返回类型的委托(delegate)看起来不太常见?
有人可以提供一个更实际的委托(delegate)协变示例吗?
最佳答案
这是我实现服务定位器的“真实世界”示例。我想创建一个类,我可以在其中注册知道如何生成某种类型实例的“工厂”委托(delegate),然后稍后再解析某种类型的实例。这是它的样子:
interface ISomeService { ... }
class SomeService : ISomeService { ... }
class IocContainer
{
private readonly Dictionary<Type, Func<object>> _factories = new Dictionary<Type, Func<object>>();
public void Register<T>(Func<T> factory)
where T: class
{
_factories[typeof(T)] = factory;
}
// Note: this is C#6, refactor if not using VS2015
public T Resolve<T>() => (T)_factories[typeof(T)]();
}
class Program
{
static void Main(string[] args)
{
var container = new IocContainer();
container.Register<ISomeService>(() => new SomeService());
// ...
var service = container.Resolve<ISomeService>();
}
}
现在,我在做什么container.Register<ISomeService>(() => new SomeService())
, Func
的协方差委托(delegate)在两个层面上发挥作用:
- 我可以传入
Func<SomeService>
并且它是可分配的,其中Func<ISomeService>
预计没有问题,因为SomeService
是ISomeService
- 在
Register
内方法,一个Func<T>
可以分配一个Func<object>
预计没有问题,因为任何引用类型都是object
如果 Func<SomeService>
无法分配给 Func<ISomeService>
, 或 Func<ISomeService>
无法分配给 Func<object>
(通过协方差),这个例子行不通。
关于c# - 委托(delegate)中的协方差,有什么例子吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31873464/