我实现了如下的抽象类:
public abstract class Pack
{
protected List<PackEntry> m_Entries;
public Int32 EntriesCount
{
get { return m_Entries.Count; }
}
public Pack()
{
m_Entries = new List<PackEntry>();
}
#region Methods: Abstract
...
#endregion
}
public sealed class PackTypeA : Pack { ... }
public sealed class PackTypeB : Pack { ... }
还有一个PackEntry
子类:
public abstract class PackEntry
{
protected Byte[] m_Data;
protected PackEntry() { }
public Byte[] GetData()
{
return m_Data;
}
public void SetData(Byte[] data)
{
m_Data = data;
}
#region Methods: Abstract
...
#endregion
}
public sealed class PackEntryTypeA : PackEntry { ... }
public sealed class PackEntryTypeB : PackEntry { ... }
这意味着派生类PackTypeA
将使用PackEntryTypeA
条目,而PackTypeB
将使用PackEntryTypeB
等等。
现在......我正在使用我的Pack
抽象类,如下面的代码片段所示:
Pack pack = useTypeA ? new PackTypeA() : new PackTypeB();
pack.AbstractMethod1();
if (condition)
pack.AbstractMethod2();
...
一切都像魅力一样,但在AbstractMethod1()
... AbstractMethodN()
内部覆盖了我对条目列表的大量工作。这需要很多像:
for (Int32 i = 0; i < m_Entries.Count; ++i)
{
PackEntryTypeA entry = (PackEntryTypeA)m_Entries[i];
...
它变得单调乏味。所以我尝试了以下方法为我的Pack
类实现泛型类型:
public abstract class Pack<T> where T : PackEntry
{
protected List<T> m_Entries;
public Int32 EntriesCount
{
get { return m_Entries.Count; }
}
public Pack()
{
m_Entries = new List<T>();
}
#region Methods: Abstract
...
#endregion
}
public sealed class PackTypeA : Pack<PackEntryTypeA> { ... }
public sealed class PackTypeB : Pack<PackEntryTypeB> { ... }
哪个更好,更好!但问题是我不能再使用以下代码片段了:
Pack pack = useTypeA ? new PackTypeA() : new PackTypeB();
因为它需要指定泛型类型(我真的可以&#39;)
Pack<PackTypeN>
我想到的最后一个解决方案是将列表移动到派生类,但它不是很优雅。有人可以帮我指点解决方案吗?
答案 0 :(得分:2)
Pack<PackEntryTypeA>
和Pack<PackEntryTypeB>
是不同的类型,因此,为了能够将它们存储在同一个变量中,它们必须具有相同的基类或接口。
public static void Main()
{
var pack = 1 == 1 ? (IPack)new PackTypeA() : (IPack)new PackTypeB();
pack.AbstractMethod1();
pack = 1 == 2 ? (IPack)new PackTypeA() : (IPack)new PackTypeB();
pack.AbstractMethod1();
}
public interface IPack { void AbstractMethod1(); }
public abstract class PackEntry { }
public sealed class PackEntryTypeA : PackEntry {}
public sealed class PackEntryTypeB : PackEntry {}
public abstract class Pack<T> : IPack where T : PackEntry
{
protected List<T> m_Entries = new List<T>();
public abstract void AbstractMethod1();
}
public sealed class PackTypeA : Pack<PackEntryTypeA>
{
public override void AbstractMethod1()
{
Console.WriteLine(m_Entries.GetType().ToString());
}
}
public sealed class PackTypeB : Pack<PackEntryTypeB>
{
public override void AbstractMethod1()
{
Console.WriteLine(m_Entries.GetType().ToString());
}
}
输出:
System.Collections.Generic.List`1[PackEntryTypeA]
System.Collections.Generic.List`1[PackEntryTypeB]