2011-03-23 70 views
1

我已經閱讀了一些其他相關的問題,但仍不能完全弄清楚如何做我們需要做的事情。使用泛型不是必須的,但似乎是我們可能獲得我們所需的唯一途徑。我們在.net 3.5中,所以我們不能使用我認爲相關的新.net 4.0的東西。假設我們有一個具有一些屬性和方法的基類Parent。我們還有一個ParentCollection,它目前實現了IEnumerable。我們還在這個類中添加了其他屬性和方法。泛型和繼承與集合

我們現在需要從Parent繼承來創建ChildA。但是我們也需要繼承ParentCollection來創建ChildACollection。然後,我們會將ChildA的同伴班作爲ChildB和ChildBCollection。

ChildACollection和ChildBCollection及其項目是唯一實際實例化的東西。父母的東西是抽象的。

ParentCollection上的方法以及Parent可以返回符合條件且可能已被操作的項目的子集。

問題是因爲這些方法正在處理集合中的項目,所以我們希望集合返回爲後代的類型。例如調用通過ChildACollection的實例在ParentCollection中定義的SomeMethod(),以便子集返回類型爲List而不是List。

有沒有辦法實現這種功能?

例僞我們正在嘗試做

public class Parent 
{ 
    public string PropA { get; set; } 
    public int PropB { get; set; } 

    public void DoSomething() { } 
} 

public class ParentCollection : IEnumerable<Parent> 
{ 
    protected List<Parent> _list = new List<Parent>(); 

    public IEnumerator<Parent> GetEnumerator() 
    { 
     return _list.GetEnumerator(); 
    } 

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 

    public List<Parent> SomeSelectMethod() 
    { 
     List<Parent> list = new List<Parent>(); 

     // DO LOGIC HERE TO DETERMINE WHAT ITEMS WILL BE IN LIST 

     return list; 
    } 

} 

public class ChildA : Parent 
{ 
    public double PropC { get; set; } 

    public void DoSomethingElse() { } 
} 

public class ChildACollection : ParentCollection 
{ 
    public void SomeChildMethod() { } 
} 

public class MyTestClass 
{ 
    public void Main() 
    { 
     ChildACollection myCollection = new ChildACollection(); 

     //HERE IS THE PROBLEM 
     List<ChildA> childList = myCollection.SomeSelectMethod(); 
    } 

} 

什麼基本上,我想利用的傳承,但不能使ChildACollection的用戶代碼必須不斷地投對象參考列表返回到ChildA對象。我的意思是內部列表將有實際的ChildA對象,而不是Parent對象,但由於該方法在ParentCollection類中,它只知道它是Parent或後代類的對象。希望這是有道理的。

幫助?

跟進問題: 我需要深深這個層次結構1倍以上的水平(孫子),增加添加方法的家長,將創建和approprate對象類型添加到列表中,也就是說,如果添加是調用ChildCollection引用時,它應該創建並添加一個Child類型,並返回對該列表中新創建的對象的引用。 Possilbe?

+0

受保護的列表 _list = new List (); 你知道你已經繼承自IEnumerable ,這實際上是一個列表,所以你不需要一個_list元素成爲類的一部分。 – 2011-03-23 15:59:44

回答

4

可以使用泛型類型參數約束:

class ParentCollection<T> where T : Parent { 
     public List<T> SomeSelectMethod() 
     { 
      List<T> list = new List<T>(); 

      // can treat T as Parent here 

      return list; 
     } 
    } 

    class ChildACollection : ParentCollection<ChildA> { 
    } 

    class ChildBCollection : ParentCollection<ChildB> { 
    } 

您也可以考慮從System.Collections.ObjectModel.Collection繼承,所以你不必實現IEnumerable。

對於後續:

我的理解是,你想有一個無參數方法Add(),其上創建了一個類型T的實例父集合,將其添加到集合,並返回它。這樣做的一個方法是對T添加額外的約束:

class ParentCollection<T> where T : new(),Parent { 
     public T Add() { 
     var item = new T(); 
     Add(item); 
     return item; 
     } 
    } 
0

所以,基本上你想要的人能夠調用SomeSelectMethod並獲得任一列表,列表,或列表?

你可以用泛型參數和一些LINQ來做到這一點。

public List<T> SomeSelectMethod<T>() 
    where T : Parent 
{ 
    return this.Where(x => x.MatchesSomeExpression && x is T).Cast<T>().ToList(); 
} 
0

您可以使ParentCollection成爲泛型類。 嘗試:

public class ParentCollection<T> : IEnumerable<T> where T:Parent

和更換每一個與該類別。

然後你就可以class ChildACollection : ParentCollection<ChildA>

0

這裏有一個解決方案。

public class ParentCollection<T> : IEnumerable<T> where T : Parent 
{ 
    protected List<T> _list = new List<T>(); 

    public IEnumerator<T> GetEnumerator() 
    { 
     return _list.GetEnumerator(); 
    } 

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 

    public virtual List<T> SomeSelectMethod() 
    { 
     List<T> list = new List<T>(); 

     // DO LOGIC HERE TO DETERMINE WHAT ITEMS WILL BE IN LIST 
     return list; 
    } 
} 

public class ChildACollection : ParentCollection<ChildA> 
{ 
    public void SomeChildMethod() 
    { 
    } 
    //You have the method inherited. 
} 
+0

這是我前往的地方。我添加了關於添加第三級繼承的後續問題。 – barrettsm 2011-03-23 18:01:18