在接口/基类C#枚举?(C# enum in interface/base class?)

2019-06-23 23:11发布

我有枚举问题

我需要做的基类或接口一个枚举(但空单)

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

之后使不同势枚举在一些父类

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

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

现在我有方法隔壁班时,我不得不使用枚举

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

I'T很糟糕的代码......在某些类我必须使用〜20个+变量

Answer 1:

有作为一个抽象的枚举(即可以在不同的子类实现)没有这样的事 - 但泛型可能是一种选择:

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


Answer 2:

令人惊讶的是我怎么经常发现人们争论为什么需要的东西,而不是回答这个问题询问或保持schtum -无论它的将是比为什么给出的询价已优先被作出不同的调查受访者浪费时间质问更有帮助其实知道答案。 回答这个没有问是没有办法有帮助的问题,OK?家伙

再回到手头的话题,我正好找到了上面的场景今天上午,并能理解为什么它会是能在一个接口或基类来定义枚举有用的,然后重新定义的同名枚举在从将碱或接口派生的类。 用于这种设计的一个用途是在对象关系映射和对照结合。 您可能有一组描述,你的派生类的属性是可绑定枚举的哪个类型的控制,如:

    public enum WebControlTextBoxProperties { }

    public enum WebControlLabelProperties { }

...等等。

既然你不知道到底哪个属性将存在一个给定的派生类,直到相关的继承生效,但既然你也不妨有消耗你的基地或接口上面枚举一致的方法,这是一个完美的,有效的设计以期望能够定义枚举在基地/界面存在 ,但准确定义它所含的成员在任何派生类的特定环境。

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



Answer 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的将只能访问类型。

不过,我个人不认为这样做我会在基类中声明的枚举的所有值的优势,仅使用I每班需要的人。

詹姆士。



Answer 4:

不,不能这样做。

请注意,许多枚举往往表明有设计有问题(很多开关结构,例如)。 检查此链接,看看如何重构这个例子: 更换条件有多态性 。



Answer 5:

没有,没有办法执行中的任何一个接口的静态。

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



Answer 6:

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

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

和仅使用枚举的相关成员在派生类中?



Answer 7:

我在工作,所以还不能完全阐明,但是这是可能的一个点。 缺点下面的代码是你无法枚举链在一起,如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; }
    }


Answer 8:

可以抽象的枚举!

为什么人们坚持声称事情是不可能的,不检查什么吗?

当然,在.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

蓝色



Answer 9:

我喜欢@Marc Gravell的接受的答案。 因为我是一个计算器,新手我不允许发表评论。 但我想补充,它是有用的同时检查枚举的基本类型 - 特别是如果你使用标志属性和预制件逐位标志测试操作...

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


Answer 10:

下面是对我工作的解决方案:

在父类中,声明领域如int,而不是枚举:

protected int state;

因此父类仍然可以使用这个值作为一个int,以便提供该值到磁盘的序列化和deserializion。

那么,谁覆盖类可以这样做:

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


文章来源: C# enum in interface/base class?