[英]C# enum in interface/base class?
我有枚舉的問題
我需要在基類或接口中創建一個枚舉(但是空的)
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;
// ...
}
}
我在代碼中看起來不好......在某些類中我必須使用~20 +變量
令人驚訝的是,我經常發現人們爭論為什么需要某些東西,而不是回答所提出的問題或保持問題 - 其中任何一個都比浪費時間質疑為什么特定的調查優先於受訪者的不同調查更有幫助。實際上知道答案。 回答沒有被問過的問題絕對沒有幫助,伙計們好嗎?!
回到手頭的主題,我今天早上完全按照上面的場景,並且能夠理解為什么能夠在接口或基類中定義Enum,然后重新定義同名的Enum是有用的。在從基類或接口派生的類中。 這種設計的一個用途是對象關系映射和控制綁定。 您可能有一組枚舉,用於描述派生類的哪些屬性可綁定到哪些類型的Control,例如:
public enum WebControlTextBoxProperties { }
public enum WebControlLabelProperties { }
...等等。
由於在相關繼承生效之前您不確切知道給定派生類將存在哪些屬性,但由於您可能還希望在基礎或接口中使用一致的方法來使用上述枚舉,因此它是完全有效的設計期望能夠定義Enum 將存在於基礎/接口中,但確切地定義它在任何派生類中的特定上下文中具有哪些成員 。
我真的希望這在C#中是可行的,因為它在VB中,因為它是一個非常有用的功能。
沒有抽象枚舉(在子類中可以有不同的實現) - 但泛型可能是一個選項:
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");
}
您應該能夠在基類中聲明枚舉,然后更改每個派生類的值,即
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只能訪問該類型。
但是,就我個人而言,我沒有看到這樣做的優點我會在基類中聲明枚舉的所有值,並且只使用每個類我需要的值。
詹姆士。
不,它無法完成。
請注意,許多枚舉通常表明設計存在問題(例如,許多開關構造)。 檢查此鏈接以查看如何重構此示例: 使用多態替換條件 。
不,沒有辦法在界面中強制執行任何靜態操作。
也許你需要重新思考你的設計。
為什么你不能在基類中定義枚舉:
class Base
{
public enum Test {A, B, C, J, H, K};
}
並且在派生類中只使用枚舉的相關成員?
我在工作,所以不能完全闡述,但這是可能的。 以下代碼的缺點是您無法將枚舉鏈接在一起,例如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; }
}
你可以抽象的枚舉!
為什么人們堅持要求在沒有檢查的情況下做出事情是不可能的?
當然,.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
藍色
我喜歡@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");
}
這是一個適合我的解決方案:
在父類中,將字段聲明為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;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.