gpt4 book ai didi

c# - 无效参数 - 继承的接口(interface)有效,但隐式转换无效。是什么赋予了?

转载 作者:行者123 更新时间:2023-11-30 22:42:16 26 4
gpt4 key购买 nike

我有一个签名为

的函数
Update(IEnumberable<INotifyPropertyChanging> things)

和一个类

doohickey : INotifyPropertyChanging, INotifyPropertyChanging{}

当我尝试做的时候

List<doohickey> doohickeys = new List<doohickey>();
Update(doohickeys);

抛出一个异常说明:

cannot convert from 'System.Collections.Generic.List<doohickey>' to 'System.Collections.Generic.IEnumerable<System.ComponentModel.INotifyPropertyChanging>'

什么给了? Doohickey继承了INotifyPropertyChanging接口(interface),List继承了IEnumerable接口(interface)!为什么简单地传递对象并期望它被丢弃却没有呢?

我已经包含了对 INotifyPropertyChanging 的引用,以表明 doohickey 实际上是一个 linq-to-sql 类;如果上下文很重要。

最佳答案

这行不通,因为 List<doohickey> 之间没有隐式转换和 IEnumerable<NotifyPropertyChanging> .您需要调用:

Update(doohickeys.Cast<INotifyPropertyChanging>());

这背后的原因是类型安全。在 C#4 中,协变/逆变被添加到语言中,这通常有助于使这些类型的转换有效。但是有一些限制,因为涉及的类型需要声明为协变/逆变,并且它仅适用于接口(interface)和委托(delegate)。

不能隐式转换List<T>的原因至 List<TBase>是,它将使此代码有效:

List<T> values = new List<T>();
// add some values...
List<TBase> bases = values;
bases.Add(new TBase()); // Woops. We broke type safety by adding a TBase to a list of T's

现在,如果您在 values 时尝试这样做类型为 IEnumerable<T> ,它在 C#4 中有效。这是因为您只能获取 IEnumerable<T> 的值。 ,因此我们无需担心添加的类型较少。因此IEnumerable<T>是协变的,声明为:

IEnumerable<out T>

在哪里out意思是“协变”。 (关键字实际上是记住变量类型中值可能采用哪种方式的最佳方式。

协变/逆变是一个相当大的主题,but this article does a good job of explaining the most important parts .如果您想了解更多信息,Eric Lippert 有一个 11-part blog post series关于功能。 Eric 是语言设计者之一。

关于c# - 无效参数 - 继承的接口(interface)有效,但隐式转换无效。是什么赋予了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4493686/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com