接口/基类中的C#枚举?

时间:2009-06-23 09:52:20

标签: c# enums virtual parent

我有枚举问题

我需要在基类或接口中创建一个枚举(但是空的)

class Base 
{
   public enum Test;
   // ???
}

并在某些父类中创建不同的枚举后

class Parent1
{
   public enum Test {A, B, C};
}

class Parent2
{
   public enum Test {J, H, K};
}

现在,当我必须使用enum

时,我有下一节课的方法
class Test<T>
{
   public void Foo(Test enum)
   {
      int value = (int) enum;
      // ...
   }
}

有没有办法做这样的事情?

如果不是我必须在每个班级使用静态内容......

class Parent1
{
   public static int A = 0;
   public static int B = 5;
   public static int C = 7;
}

class Parent2
{
   public static int J = 1;
   public static int H = 3;
   public static int K = 6;
}

class Test<T>
{
   public void Foo(int enum)
   {
      int value = enum;
      // ...
   }
}

我在代码中看起来不好......在某些类中我必须使用~20 +变量

10 个答案:

答案 0 :(得分:27)

令人惊讶的是,我经常发现人们争论为什么需要什么,而不是回答问题或保持schtum - 其中任何一个都比浪费时间质疑更有帮助为什么< / em>一个特定的询问已经优先于不同的询问,被访者实际上知道答案。回答没有被问过的问题绝对没有帮助,伙计们好吗?!

回到手头的主题,我今天早上完全按照上面的场景,并且能够理解为什么能够在接口或基类中定义Enum,然后重新定义它是有用的-named枚举在从基类或接口派生的类中。这种设计的一个用途是对象关系映射和控制绑定。您可能有一组枚举,用于描述派生类的哪些属性可绑定到哪些类型的Control,例如:

    public enum WebControlTextBoxProperties { }

    public enum WebControlLabelProperties { }

......等等。

由于在相关继承生效之前,您不确切知道给定派生类将存在哪些属性,但由于您可能还希望在基础或接口中使用一致的方法来使用上述枚举,因此它是完美的 - 期望能够在基础/接口中定义Enum 将存在的有效设计,但在任何派生类的特定上下文中准确定义它具有哪些成员

我真的希望这在C#中是可行的,因为它在VB中,因为它是一个非常有用的功能。

答案 1 :(得分:25)

没有抽象枚举(在子类中可以有不同的实现) - 但泛型可能是一个选项:

class Base<T> where T : struct {
    private T value;
    public void Foo(T value) {
        this.value = value;
    }
}
class Parent1 : Base<Parent1.Enum1> {
    public enum Enum1 {A, B, C};
}
class Parent2 : Base<Parent2.Enum2> {
    public enum Enum2 { J, H, K };
}

唯一的问题是,这并不强制只有枚举可用 - 你可以在运行时执行此操作 - 例如在类型初始值设定项中:

static Base() {
    if (!typeof(T).IsEnum) throw new InvalidOperationException(
         typeof(T).Name + " is not an enum");
}

答案 2 :(得分:3)

您应该能够在基类中声明枚举,然后更改每个派生类的值,即

class MyClass
{
    public enum TestEnum { }

    public MyClass()
    {
    }
}

class MyDerivedClass
{
    public enum TestEnum { value1, value2, value3 }

    public MyDerivedClass()
    {
    }
}

MyDervied类可以访问TestEnum.value1,TestEnum.value2,TestEnum.value3,而MyClass只能访问该类型。

但是,我个人并不认为这样做有什么好处我会在基类中声明枚举的所有值,并且只使用每个类我需要的值。

詹姆斯。

答案 3 :(得分:1)

不,它无法完成。

请注意,许多枚举通常表明设计存在问题(例如,许多开关构造)。请查看此链接,查看如何重构此内容的示例:Replace conditional with polymorphism

答案 4 :(得分:0)

不,没有办法在界面中强制执行任何静态操作。

也许您需要重新考虑您的设计。

答案 5 :(得分:0)

为什么你不能在基类中定义枚举:

class Base 
{
   public enum Test {A, B, C, J, H, K};
}

在派生类中只使用枚举的相关成员吗?

答案 6 :(得分:0)

我在工作,所以无法详细说明,但这有可能达到一定程度。以下代码的缺点是您无法将枚举链接在一起,例如TextBoxProperties和MyCustomTextBoxProperties:TextboxProperties

这是代码。

    public enum Test
    {

    }

    public enum ThisTest
    {
        MyVal1,
        MyVal2,
        MyVal3
    }

    public abstract class MyBase
    {
        public Test MyEnum { get; set; }
    }

    public class MyDerived : MyBase
    {
        public new ThisTest MyEnum { get; set; }
    }

答案 7 :(得分:0)

CAN 摘要ENUM

为什么人们坚持要求在没有检查的情况下做出事情是不可能的?

当然,.NET文档对此有点模糊,但System.Enum类是枚举的抽象。您可以将System.Enum用作仅接受枚举值的变量,并且可以通过此类访问枚举的名称或值类型值。

例如:

        // abstracted enumeration value
        Enum abstractEnum = null;

        // set to the Console-Color enumeration value "Blue";
        abstractEnum = System.ConsoleColor.Blue;

        // the defined value of "ConsoleColor.Blue" is "9":
        // you can get the value via the ToObject method:
        Console.WriteLine((int)Enum.ToObject(abstractEnum.GetType(), abstractEnum));

        // or via the GetHashCode() method:
        Console.WriteLine(abstractEnum.GetHashCode());

        // the name can also be acessed:
        Console.WriteLine(Enum.GetName(abstractEnum.GetType(), abstractEnum));

以上代码的输出:

9

9

答案 8 :(得分:0)

我喜欢@Marc Gravell的接受答案。 由于我是stackoverflow-newbie,我不允许发表评论。但我想补充一点,检查枚举的基础类型是有用的 - 特别是如果你使用Flag属性并执行逐位标记测试操作......

if ( !typeof(T).IsEnum || typeof(int) != Enum.GetUnderlyingType(typeof(T)) )
{
     throw new InvalidOperationException( typeof(T).Name + " is not an enum");
}

答案 9 :(得分:0)

这是一个适合我的解决方案:

在父类中,将字段声明为int,而不是枚举:

protected int state;

所以父类仍然可以将此值用作int,以便为磁盘提供此值的序列化和反序列化。

然后,谁覆盖课程可以做到这一点:

enum states{
  state1, state2
}

this.state = state1.toInt();

并且可以像这样访问实际值:

...
if (this.state == states.state1.toInt()){
      ...
}
else{
     ...
}

其中toInt()在静态类中定义如下:

public static class Utils
{

    public static int toInt(this state s)
    {
        return (int)s;
    }
 }