返回具有公共基类的不同类型的列表

时间:2013-10-05 00:07:01

标签: c# oop generics

我正在设计一个应返回实例列表的方法,每个实例实际上都是不同的数据类型。

以下是我的设计草案,我需要一个推荐

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;
    }
}

我的问题是什么是最好的设计?我可以更好地使用泛型吗?

1 个答案:

答案 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;
        ...
    }
}