我的小脑袋无法为这个问题找到一个优雅的解决方案。假设我有这样的课程:
public class Foo<T>
{
public RecordType Type { get; set; }
public T Value { get; set; }
}
RecordType
可能看起来像这样:
public enum RecordType
{
EmptyRecord,
BooleanRecord,
IntegerRecord,
StringRecord,
ByteRecord
}
目标是统一处理IEnumerable<Foo<T>>
迭代和/或打开RecordType
并执行操作,同时尽可能避免装入内在类型。另外,使用工厂从工厂方法创建这些Foo
会很好。
我在基类或接口中有一些快速实现的通用性,我想出的任何东西都没有回答这个看似非常简单的问题。
小编辑: 我应该提到我的主要目标是使用.Value而不强制调用者进行强制转换。
答案 0 :(得分:2)
您可以引入非通用接口IFoo:
public interface IFoo
{
RecordType Type { get; set; }
}
由通用Foo类实现:
public class Foo<T> : IFoo
{
public T Value { get; set; }
}
并创建一个工厂方法,根据RecordType创建一个Foo实例:
public static IFoo CreateFoo(RecordType type)
{
switch (type)
{
case RecordType.Bool: return new Foo<bool>();
// ...
}
}
以这种方式创建Foo实例后,您还无法访问该值,因为您还不知道类型参数。但您可以使用Type属性检查类型并执行相应的强制转换:
IFoo foo = CreateFoo(RecordType.Bool);
if (foo.Type == RecordType.Bool)
{
Foo<bool> boolFoo = (Foo<bool>)foo;
bool value = boolFoo.Value;
}
如果您有一个适用于Foo对象的方法,例如:
void DoIt<T>(IEnumerable<Foo<T>> foos)
{
foreach (Foo<T> foo in foos)
{
Qux(foo.Value);
}
}
并且有一个可枚举的IFoo对象,你可以使用Cast / OfType:
IEnumerable<IFoo> foos = // ...
DoIt<bool>(foos.OfType<Foo<bool>>());
所以,基本上,你使用Foo&lt; T&gt;当你在编译时知道T,如果你在运行时知道T,则为IFoo。 IFoo需要检查以将其变成Foo&lt; T&gt;。对于某些T在运行时。