通过基础构造函数提供'this'

时间:2013-07-30 09:31:06

标签: c# .net design-patterns generics enumeration

我有一个枚举的基类,看起来类似于下面的例子。我的实际实现涵盖了更多,如显式和隐式转换,反射,标志和异常处理,但基本上,就是这样:

public abstract class Enumeration<T> {

    // enum value
    protected readonly T _value;

    // collection of all values
    private static readonly HashSet<Enumeration<T>> _values
       = new HashSet<Enumeration<T>>();

    public T Value {
        get { return _value; }
    }

    // returns all values
    public static IEnumerable<Enumeration<T>> GetValues() {
        return _values.AsEnumerable();
    }
}

现在,每当我想要某个类型的枚举时(可能是字符串,整数等等,我不像通常的C#enum那样被笼装),我可以这样声明:

public sealed class MyEnum : Enumeration<string> {

    public static readonly MyEnum EnumVal1 = new MyEnum("Val1!");
    public static readonly MyEnum EnumVal2 = new MyEnum("Val2!");
    public static readonly MyEnum EnumVal3 = new MyEnum("Val3!");

}

使用私有或公共构造函数使其可扩展或不扩展:

public MyEnum(string enumVal) : base(value: enumVal) {}

将值传递给基本ctor:

protected Enumeration(T value) {
    _value = value;
    _values.Add(this);
}

这适用于string,int,double等类型。但是如果我想枚举复杂的对象呢?

public sealed class ComplexObj: Enumeration<ComplexObj> {

    public static readonly ComplexObj Val1 = new ComplexObj("val1", 455, null);

}

这里的问题开始了,因为我无法将实例化对象传递给基础构造函数:

public ComplexObj(string name, int someval, string another)
    : base(this) {} // doesn't work

将一个新对象传递给构造函数会导致......你知道:)

: base(new ComplexObj(name, someval, another)) {} // lol

我怎么能解决这个问题?有没有办法将对象本身传递给基础构造函数?

1 个答案:

答案 0 :(得分:3)

这是一种我不会使用的枚举,但如果您愿意这样做,那么这就是解决方案:

public sealed class MyComplexObjEnum : Enumeration<ComplexObj>
{
    public MyComplexObjEnum(ComplexObj enumVal) : base( enumVal) { }
    public static readonly MyComplexObjEnum EnumVal1 = new MyComplexObjEnum(new ComplexObj("val1", 455, null));
    public static readonly MyComplexObjEnum EnumVal2 = new MyComplexObjEnum(new ComplexObj("val2", 456, null));
    public static readonly MyComplexObjEnum EnumVal3 = new MyComplexObjEnum(new ComplexObj("val3", 457, null));
}

public class ComplexObj 
{
    private readonly string _a;
    private readonly int _b;
    private readonly string _c;

    public ComplexObj(string a, int b, string c)
    {
        _a = a;
        _b = b;
        _c = c;
    }
}