簡體   English   中英

如何創建自己的通用列表類?

[英]How to create my own generic list class?

我有這個 :

public class CChainElement
{
    public CChainElement m_Prev, m_Next;
}

public class CChainList : IEnumerable
{
    public CChainElement m_First;

    internal void Add(CChainElement Element)
    {
        if (m_First != null)
            m_First.m_Prev = Element;

        Element.m_Next = m_First;
        m_First = Element;
    }
}

public class CEntity : CChainElement
{
}

public class CItem : CEntity
{
}

public class CTest
{
    void Test()
    {
        CChainList AllItem = new CChainList();
        CItem Item = new CItem();

        AllItem.Add(Item);

        CItem FirstItem = AllItem.m_First as CItem;
        CItem SecondItem = FirstItem.m_Next as CItem;
    }
}

我想切換到這樣的內容:

public class CChainElement<T> where T : CChainElement<T>
{
    public T m_Prev, m_Next;
}

public class CChainList<T> : IEnumerable where T : CChainElement<T>
{
    public T m_First;

    internal void Add(T Element)
    {
        if (m_First != null)
            m_First.m_Prev = Element;

        Element.m_Next = m_First;
        m_First = Element;
    }
}

public class CEntity : CChainElement<CEntity>
{
}

public class CItem : CEntity
{
}

public class CTest
{
    void Test()
    {
        CChainList<CItem> AllItem = new CChainList<CItem>();
        CItem Item = new CItem();

        AllItem.Add(Item);

        CItem FirstItem = AllItem.m_First;  // Yeepee, no more "as CItem" ..! ;-)
        CItem SecondItem = FirstItem.m_Next;
    }
}

而且我得到一個錯誤,即CItem can't be converted to CChainElement<CItem>

所以我的問題是:是否仍然有約束public class CChainElement<T>所以即使它不是直接繼承自CChainElement,它也會優雅地使用CItem?

我的目標顯然是,從CChainElement<T>繼承的所有類都可以與我的通用列表類一起列出,同時避免顯式轉換。

在此先感謝您的幫助!

編輯:在我的整個項目中,CEntity作為抽象類用於許多不同的事情(即:我可以通過與Items相似的方式來操縱Monsters),因此不能將其更改為通用CEntity<T>

CChainElement不應該是通用的。 唯一應該變成泛型的是CChainList

public class CChainElement
{
    public CChainElement m_Prev, m_Next;
}

public class CChainList<T> : IEnumerable
   where T : CChainElement
{
    public T m_First;

    internal void Add(T Element)
    {
        if (m_First != null)
            m_First.m_Prev = Element;

        Element.m_Next = m_First;
        m_First = Element;
    }
}

public class CEntity : CChainElement
{
}

public class CItem : CEntity
{
}

public class CTest
{
    void Test()
    {
        CChainList<CItem> AllItem = new CChainList<CItem>();
        CItem Item = new CItem();

        AllItem.Add(Item);

        CItem FirstItem = AllItem.m_First;
        CItem SecondItem = FirstItem.m_Next;
    }
}

好吧,這是一個有趣的小問題。 您需要進行以下更改:

public class CEntity<T> : CChainElement<T> where T : CChainElement<T> { ... }

public class CItem : CEntity<CItem> { ... }

然后,這將按照您想要的方式工作:

var allItems = new CChainList<CItem> { new CItem(), new CItem() };

// Both of these are now of type Item.
var firstItem = allItems.m_First;
var secondItem = firstItem.m_Next;

另一個選擇是使ChainElement成為通用接口:

public interface IChainElement<T> where T : IChainElement<T>
{
    T Previous { get; set; }
    T Next { get; set; }
}

但是,然后您必須將屬性顯式添加到要放入列表中的每個類:

public class Entity { }

public class Item : Entity, IChainElement<Item>
{
    public Item Previous { get; set; }
    public Item Next { get; set; }
}

無論哪種方式,最終都需要修改要在列表中使用的所有類。


順便說一句,您可能想使用一組更好的命名約定。 C開頭所有類名,使用InitialCapitals命名參數,使用locals開頭,以m_開頭的公共字段使代碼難以閱讀! 我建議這樣的事情:

public class ChainElement<T> where T : ChainElement<T>
{
    public T Previous { get; set; }
    public T Next { get; set; }
}

public class ChainList<T> : IEnumerable where T : ChainElement<T>
{
    public T First { get; private set; }

    public void Add(T element)
    {
        if (First != null)
            First.Previous = element;

        element.Next = First;
        First = element;
    }

    public IEnumerator GetEnumerator() { throw new NotImplementedException(); }
}

public class Entity<T> : ChainElement<T> where T : ChainElement<T> { }

public class Item : Entity<Item> { }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM