具有通用子类型的摘要 Class
Abstract Class with Generic Subtype
我实现了如下抽象 class:
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
subclass 还有:
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 { ... }
这意味着派生的 class PackTypeA
将使用 PackEntryTypeA
条目,而 PackTypeB
将使用 PackEntryTypeB
等等。
现在...我正在使用我的 Pack
摘要 class,如以下代码片段所示:
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
class:
实现泛型类型
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();
因为它需要指定泛型类型(我真的不能):
Pack<PackTypeN>
我想出的最后一个解决方案是将列表移至派生的 classes,但这不是很优雅。有人可以给我指出解决方案吗?
Pack<PackEntryTypeA>
和 Pack<PackEntryTypeB>
是不同的类型,因此,为了能够将它们存储在同一个变量中,它们必须具有相同的基础 class 或接口。
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]
我实现了如下抽象 class:
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
subclass 还有:
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 { ... }
这意味着派生的 class PackTypeA
将使用 PackEntryTypeA
条目,而 PackTypeB
将使用 PackEntryTypeB
等等。
现在...我正在使用我的 Pack
摘要 class,如以下代码片段所示:
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
class:
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();
因为它需要指定泛型类型(我真的不能):
Pack<PackTypeN>
我想出的最后一个解决方案是将列表移至派生的 classes,但这不是很优雅。有人可以给我指出解决方案吗?
Pack<PackEntryTypeA>
和 Pack<PackEntryTypeB>
是不同的类型,因此,为了能够将它们存储在同一个变量中,它们必须具有相同的基础 class 或接口。
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]