我正在设计一个应返回实例列表的方法,每个实例实际上都是不同的数据类型。
以下是我的设计草案,我需要一个推荐
public class abstract Base
{
//DataType is an enum
public abstract DataType Type { get; set; }
public abstract BaseType Value { get; set; }
}
public abstract class BaseType
{
}
public class MyString:BaseType
{
}
public class MyInt:BaseType
{
}
//string for example
public class Type1:Base
{
public override DataType Type
{
get { return DataType.Type1; }
set;
}
public override BaseType Value
{
get { return new MyString("a"); }
set;
}
}
public class Type2:Base
{
public override DataType Type
{
get { return DataType.Type2; }
set;
}
public override BaseType Value
{
//MyInt for example
get { return new MyInt(10); }
set;
}
}
方法应该是
List<Base> GetValues();
调用者应该写类似的东西
List<Base> values = GetValues();
foreach(var value in values)
{
switch(value.Type)
{
case DataType.MyString:
MyString str = value.Value as MyString;
break;
case DataType.MyInt:
MyInt str = value.Value as MyInt;
break;
}
}
我的问题是什么是最好的设计?我可以更好地使用泛型吗?
答案 0 :(得分:1)
我建议使用通用基类:
public abstract class Base<T>
where T : BaseType
{
public abstract DataType Type { get; }
public abstract T Value { get; set; }
}
Type1现在是:
public class Type1 : Base<MyString>
{
public override DataType Type
{
get { return DataType.MyString; }
}
public override MyString Value
{
get;
set;
}
}
但是,我不知道GetValues
是什么。如果它返回相同类型的值列表,则它也应该是通用的:
public List<Base<T>> GetValues<T>()
where T : BaseType
{
return theList;
}
如果它返回不同类型的元素,则可以使用另一个非泛型基类:
public abstract class Base
{
public abstract DataType Type { get; }
}
public abstract class Base<T> : Base
where T : BaseType
{
public abstract T Value { get; set; }
}
GetValues
方法是:
public List<Base> GetValues()
{
return theList;
}
请注意,我将非泛型部分移动到非泛型基类中,以便您仍然可以使用DataType属性。
您需要将值强制转换为相应的类型才能访问Value
属性:
List<Base> values = GetValues();
foreach (Base value in values)
{
switch (value.DataType)
{
case DataType.MyString:
MyString myString = value as MyString;
...
case DataType.MyInt:
MyInt myInt = value as MyInt;
...
}
}
您似乎只使用DataType
属性来获取有关对象类型的信息。这不是必需的。您可以使用is
运算符:
foreach (Base value in values)
{
if (value is MyString)
{
MyString myString = value as MyString;
...
}
else if (value is MyInt)
{
MyInt myInt = value as MyInt;
...
}
}