2015-03-30 36 views
0

构件其他接口I'got与理解为什么具有这种类的问题:通用C#类不实施与中的第一个

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被保证为b e类型ISectionItem。可能的解决方案之一可能是创建addidiotional或ISection与泛型ISection<T>,但我不知道它会如何表现,当我想要与Xaml一起使用。有没有让编译器知道接口符合要求?

EDIT1:在ISection改变IEnumerableLinkedList,因为它是一个糟糕的概念和答案注重从题目有点撇开我是最感兴趣的

EDIT2:我的问题是更直接的原因牛逼实施ISectionItem是不允许,但我注意到我是多么愚蠢。接口ISection允许在一个列表Section<T>中使用几个不同的类实现ISectionItem

伙计们,你们的答案是正确的,但我会将Olivier's标记为答案,因为它显示了解决这个问题的方法。

回答

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;但是,您的界面允许您添加与T不同的ISectionItem

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> ==>false!

这两个集合只是两个不同的集合,没有任何赋值兼容性。

+0

不是,不能'IEnumerable ',必须是'IEnumerable ' – 2015-03-30 23:46:08

+0

是的。我们需要将泛型类型参数添加到接口以使其工作。 – 2015-03-31 00:04:27

2

不符合符合要求。

考虑从界面以下

Section<ItemX> xSection = new Section<ItemX>; 
//xSection.Items = BindingList<ISectionItem>(); 
ISection xISection = xSection; 
xISection.Items = BindingList<ISectionItem>(); 

的契约是:Items可以分配给任何集合ISectionItem

+0

好吧,你是对的,但如果我改变什么从“IEnumerable”到“ISection”中的LinkedList?为什么它还不够? – 2015-03-31 00:02:25

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>();} 
    } 
}