2009-06-23 90 views
12

我有枚举问题在接口/基类中的C#枚举?

我需要做的基类或接口(但空单)

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个+变量

+2

也许这是一个好主意,重新检查你的假设 - 你为什么需要这个?试着重新解释这个问题,以包括你实际尝试完成的事情,而不是专注于你接近问题的方式。 :) – Rytmis 2009-06-23 09:55:13

+0

什么是你想用它,真的吗?具有相同枚举的不同实现似乎与枚举的目的是相反的...... – Guffa 2009-06-23 09:57:07

+3

@Groo:不,它将值添加到枚举中,这是一个具有对象特定值的抽象枚举,但实现一个一致的界面,所以它的成员可以被传递。马克的回答是我见过的最好的答案。 – 2011-09-13 03:03:35

回答

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

以及其最佳的解决方案,我不能使用的只有一件事: 抽象公共类DB 其中T:基本,INTERF,新的() 我明白为什么,我必须使用静态INT的不枚举然后 – kaem 2009-06-23 10:33:41

+0

“有不是抽象枚举(可以在子类中有不同的实现) - 但泛型可能是一个选项:“ - 错误! System.Enum是所有枚举的抽象基础 – 2013-05-24 00:47:57

+0

@SimonBridge请参阅问题的上下文 – 2013-05-24 06:21:31

0

不,在界面中无法强制任何静态内容。

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

0

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

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

1

不,不能这样做。

请注意,许多枚举通常表示设计有问题(例如,许多开关结构)。查看此链接以查看如何重构此示例:Replace conditional with polymorphism

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只能访问该类型。

但是,我个人并没有看到这样做的好处,我将在基类中声明枚举的所有值,并仅使用每类所需的值。

James。

27

令人惊讶我怎么经常发现人们争论为什么东西是必需的,而不是回答这个问题询问或保持schtum - 无论其是不是浪费时间质疑更有帮助,为什么给定的调查已经取得了而不是被调查者实际知道的答案。回答没有问过的问题绝对没有帮助,好吧?!

回到手头的话题,我已经在上午完成了上述场景,并且可以理解为什么能够在接口或基类中定义枚举是有用的,然后重新定义在源自基础或接口的类中的同名Enum。这种设计的一个用处在于对象关系映射和控制绑定。您可能有一组枚举说明派生类的哪些属性可以绑定到哪些类型的控件,例如:

public enum WebControlTextBoxProperties { } 

    public enum WebControlLabelProperties { } 

...等等。

既然您不知道给定的派生类将存在哪些属性,直到相关的继承生效,但由于您可能还希望在您的基础或接口中使用上述枚举的一致方法,所以它是完美,有效的设计,以期望能够定义枚举将在基地/界面存在,但确切定义它在任何派生类特定的上下文是什么会员

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

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

YOU CAN 摘要:枚举!

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

肯定的是,.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)); 

从上面的代码的输出:

0

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

if (!typeof(T).IsEnum || typeof(int) != Enum.GetUnderlyingType(typeof(T))) 
{ 
    throw new InvalidOperationException(typeof(T).Name + " is not an enum"); 
} 
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; 
    } 
}