【问题标题】:IList<T>, IEnumerable<T> and ObservableCollection<T>IList<T>、IEnumerable<T> 和 ObservableCollection<T>
【发布时间】:2012-05-28 21:33:59
【问题描述】:

我定义了两个类

public class PostleitzahlList : ObservableCollection<Postleitzahl> {
}

public class Postleitzahl : IPostleitzahl {
}

现在我有一个包含

的服务类
PostleitzahlList _postleitzahlList;

这个服务类还必须实现一个返回_postleitzahlList的服务接口的属性——但是这个接口只知道IPostleitzahl——它不知道PostleitzahlListPostleitzahl。此属性应用于 WPF 中的绑定。

我现在正在尝试声明和实现此属性。我试过了

    public ObservableCollection<IPostleitzahl> PostleitzahlList {
        get { return this._postleitzahlList; }
    }

    public IList<IPostleitzahl> PostleitzahlList {
        get { return this._postleitzahlList; }
    }

但两者都不起作用。 休耕似乎奏效了:

    public IEnumerable<IPostleitzahl> PostleitzahlList {
        get { return this._postleitzahlList; }
    }

我现在问我 1.为什么第一次和第二次尝试不起作用? 2. 解决这个问题的最佳方案是什么?

【问题讨论】:

  • 您是否尝试过修改 PostleitzahlList 以扩展 ObservableCollection&lt;IPostleitzahl&gt;?在我看来,您应该在这里使用接口而不是实现。
  • 为什么不只是public PostleitzahlList PlList { get { return this._postleitzahlList; } }。这应该可以正常工作。

标签: c# .net collections .net-4.0 observablecollection


【解决方案1】:

你能把 PostleitzahlList 改成

public class PostleitzahlList : ObservableCollection<IPostleitzahl> {
}

元素类型为IPostleitzahl 而不是Postleitzahl

解释见@jon skeet 回答

【讨论】:

  • 哎哟 - 不是指向 skeet 答案的有效链接。你只是触发了活着的传奇:)
【解决方案2】:

问题在于协方差。 ObservableCollection&lt;Postleitzahl&gt; 不是 ObservableCollection&lt;IPostleitzahl&gt;,列表也是如此。这是一个为什么不这样做的例子:

ObservableCollection<string> strings = new ObservableCollection<string>();

// This is invalid, but it's what you're trying to do, effectively.
ObservableCollection<object> objects = strings;

// This would have to work... it's fine...
objects.Add(new object());

// And this should be fine too...
string x = strings[0];

... 但正如您所见,您现在正尝试获取非字符串引用并将其存储在字符串变量中。唯一可行的结果是执行时失败......而泛型的一半是将错误检测推送到编译时

现在IEnumerable&lt;T&gt;T 中的协变,因为您不能通过它添加任何项目 - 这使得应用这种转换是安全的:

// There's nothing you can do to violate type safety here...
Observable<string> strings = new ObservableCollection<string>();
IEnumerable<object> objects = strings;

如需了解更多信息,请阅读covariance and contravariance in generics in MSDN

您需要IPostleitzahl 接口吗?如果您只是通过ObservableCollection&lt;Postleitzahl&gt;IList&lt;Postleitzahl&gt; 公开属性,那就没问题了。或者,您可以将变量更改为 ObservableCollection&lt;IPostleitzahl&gt;,然后通过创建 Postleitzahl 实例来填充它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-05
    • 1970-01-01
    • 1970-01-01
    • 2018-01-05
    • 2011-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多