我理解为什么要有这样的课时会遇到问题:
public class Section<T> : ISection
where T : ISectionItem
{
public string Title { get; set; }
public LinkedList<T> Items { get; set; }
}
实现这样的界面:
public interface ISection
{
string Title { get; set; }
LinkedList<ISectionItem> Items { get; set; }
}
我收到编译错误说:
Error 1
'JobTracker.Model.CV.Section<T>' does not implement interface member
'JobTracker.Model.CV.ISection.Items'.
'JobTracker.Model.CV.Section<T>.Items' cannot implement
'JobTracker.Model.CV.ISection.Items'
because it does not have the matching return type of
'System.Collections.Generic.IEnumerable<JobTracker.Model.CV.ISectionItem>'.
应该可以,因为T保证是ISectionItem
类型。可能的解决方案之一可能是使用泛型ISection
创建addidiotional或替换ISection<T>
,但我不知道当我想要将它与Xaml一起使用时它将如何表现。有没有让编译器知道接口符合要求?
EDIT1:在IEnumerable
中将LinkedList
更改为ISection
,因为这是一个糟糕的概念,而且回答的焦点与我最感兴趣的主题有关。
EDIT2:我的问题更多地针对为什么不允许实施ISectionItem
,但我注意到我是多么愚蠢。接口ISection
允许在一个列表ISectionItem
中使用实现Section<T>
的多个不同类。
大家,你的答案都是正确的,但我会将Olivier的标记作为答案,因为它也显示了这个问题的解决方案。
答案 0 :(得分:2)
不符合要求。
考虑以下
Section<ItemX> xSection = new Section<ItemX>;
//xSection.Items = BindingList<ISectionItem>();
ISection xISection = xSection;
xISection.Items = BindingList<ISectionItem>();
界面中的合同是Items
可以分配给 ISectionItem
的任何集合。
答案 1 :(得分:2)
如果您通过界面访问Items
,则可以为其分配一个不是LinkedList<T>
的集合,这会导致错误。由于Items
也有一个setter,因此它不能是IEnumerable<T>
;但是,您可以像这样实现它
private LinkedList<T> _items;
public IEnumerable<T> Items {
get { return _items; }
set {
var linkedList = value as LinkedList<T>;
if (linkedList != null) {
_items = linkedList;
} else {
_items = new LinkedList<T>(value);
}
}
}
要使其正常工作,您必须将界面更改为:
public interface ISection<T>
where T : ISectionItem
{
string Title { get; set; }
IEnumerable<T> Items { get; set; }
}
并声明这个类
public class Section<T> : ISection<T>
where T : ISectionItem
{
...
}
您的修改无法解决问题。通过您的课程,您可以指定实施LinkedList<T>
的任何T
ISectionItem
;但是,您的界面允许您添加与ISectionItem
不同的T
。
class DerivedA : ISectionItem
{
...
}
class DerivedB : ISectionItem
{
...
}
ISection s = new Section<DerivedA>();
s.AddLast(new DerivedB()); // The collection in `s` is a `LinkedList<DerivedA>` boom!
故事的寓意是集合项的继承(或者一般来说:某种类型的泛型类型参数)不定义集合的继承。
让T'
来自T
。
Collection<T'>
来自Collection<T>
==&gt;的假!强>
这两个集合只是两个不同的集合,没有任何赋值兼容性。
答案 2 :(得分:0)
如果您可以将Items
接口属性设置为只读,那么最简单的路由似乎是将显式接口实现添加为重载:
public interface ISection
{
string Title { get; set; }
IEnumerable<ISectionItem> Items { get; }
}
public class Section<T> : ISection
where T : ISectionItem
{
public string Title { get; set; }
public LinkedList<T> Items { get; set; }
IEnumerable<ISectionItem> ISection.Items
{
get {return Items.Cast<ISectionItem>();}
}
}