我有这个:
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>
因此它会优雅地采用CItem,即使它不直接从CChainElement继承?
我的目标显然是从CChainElement<T>
继承的所有类都可以与我的通用列表类一起列出,同时避免显式转换。
提前感谢您的帮助!
编辑:在我的完整项目中,CEntity用于许多不同的事物作为抽象类(即:我可以通过类似于物品的方式操纵怪物),所以它不能被更改为通用CEntity<T>
。
答案 0 :(得分:0)
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;
}
}
答案 1 :(得分:0)
嗯,这是一个有趣的小问题。您需要进行以下更改:
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
命名参数和本地人,以及以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> { }