作为枚举值的高级对象
Advanced objects as value of Enum
有没有办法做类似的事情:
public class Test { public int num; public string name;}
public enum MyEnum
{
Foo = new Test(){ num = 1, name = "hi" },
Bar = new Test() { num = 2, name = "Cool" },
}
这样我就可以做类似的事情:
string s = MyEnum.Foo.name;
int i = MyEnum.Bar.num;
基本上,我有一大堆我觉得不需要的项目 class。我喜欢能够直接从枚举中引用类型。 (我可以一一列举)
***** 编辑:*****
尽管很多人说这是不可能的,但我还是能够获得所需的功能(请参阅下面的选定答案)
你不能那样做,因为 C# 中的 enum
是原始整数之上的精简抽象。但是,您可以使用 "enum pattern",这实际上是 Java 实现枚举的方式:
public sealed class MyTestEnum
{
public int Num { get; private set; }
public string Name { get; private set; }
private MyTestEnum(int num, string name)
{
Num = num;
Name = name;
}
public static readonly Foo = new MyTestEnum(1, "hi");
public static readonly Bar = new MyTestEnum(2, "cool");
}
请注意,私有构造函数确保 class 的唯一实例是您从 class 定义本身创建的 static readonly
实例。这也使得在不实现 operator==
或 Equals()
的情况下比较枚举实例 class 与 ==
是安全的。但是请注意,MyTestEnum
变量可能是 null
,而不是常规枚举变量。
如果您坚持使用枚举,您可以在定义中指定底层枚举类型:
public enum MyEnum :int
{
hi =1,
Cool =2
}
public class test
{
public void hello()
{
var e = MyEnum.Cool;
var intValue = (int)e;
var stringValue = e.ToString();
}
}
可以通过使用属性和扩展方法来获得所需的功能。
首先创建一个属性:
[AttributeUsage(System.AttributeTargets.All, AllowMultiple = false)]
public sealed class TestAttribute : Attribute
{
public TestAttribute(int num, string name)
{
Num = num;
Name = name;
}
public int Num { get; private set; }
public string Name { get; private set; }
}
然后注释"advanced"枚举类型:
public enum MyEnum
{
[Test(1, "hi")]
Foo,
[Test(2, "cool")]
Bar,
}
然后为高级枚举创建扩展:
public static class TestExtensions
{
public static int Num(this MyEnum val)
{
int n = 0;
FieldInfo fi = val.GetType().GetField(val.ToString());
TestAttribute[] attrs =
fi.GetCustomAttributes(typeof(TestAttribute),
false) as TestAttribute[];
if (attrs.Length > 0)
{
n = attrs[0].Num;
}
return n;
}
public static string Name(this MyEnum val)
{
string n = "";
FieldInfo fi = val.GetType().GetField(val.ToString());
TestAttribute[] attrs =
fi.GetCustomAttributes(typeof(TestAttribute),
false) as TestAttribute[];
if (attrs.Length > 0)
{
n = attrs[0].Name;
}
return n;
}
public static string Title(this MyEnum val)
{
return Enum.GetName(val.GetType(), val);
}
}
然后使用枚举:
public class Program
{
static void Main(string[] args)
{
Console.WriteLine(MyEnum.Bar.Name());
foreach(MyEnum e in Enum.GetValues(typeof(MyEnum)))
{
EnumTest(e);
}
}
public static void EnumTest(MyEnum e)
{
Console.WriteLine(
String.Format("{0}'s name={1}: num={2}", e.Title(), e.Name(), e.Num()));
}
}
有没有办法做类似的事情:
public class Test { public int num; public string name;}
public enum MyEnum
{
Foo = new Test(){ num = 1, name = "hi" },
Bar = new Test() { num = 2, name = "Cool" },
}
这样我就可以做类似的事情:
string s = MyEnum.Foo.name;
int i = MyEnum.Bar.num;
基本上,我有一大堆我觉得不需要的项目 class。我喜欢能够直接从枚举中引用类型。 (我可以一一列举)
***** 编辑:*****
尽管很多人说这是不可能的,但我还是能够获得所需的功能(请参阅下面的选定答案)
你不能那样做,因为 C# 中的 enum
是原始整数之上的精简抽象。但是,您可以使用 "enum pattern",这实际上是 Java 实现枚举的方式:
public sealed class MyTestEnum
{
public int Num { get; private set; }
public string Name { get; private set; }
private MyTestEnum(int num, string name)
{
Num = num;
Name = name;
}
public static readonly Foo = new MyTestEnum(1, "hi");
public static readonly Bar = new MyTestEnum(2, "cool");
}
请注意,私有构造函数确保 class 的唯一实例是您从 class 定义本身创建的 static readonly
实例。这也使得在不实现 operator==
或 Equals()
的情况下比较枚举实例 class 与 ==
是安全的。但是请注意,MyTestEnum
变量可能是 null
,而不是常规枚举变量。
如果您坚持使用枚举,您可以在定义中指定底层枚举类型:
public enum MyEnum :int
{
hi =1,
Cool =2
}
public class test
{
public void hello()
{
var e = MyEnum.Cool;
var intValue = (int)e;
var stringValue = e.ToString();
}
}
可以通过使用属性和扩展方法来获得所需的功能。 首先创建一个属性:
[AttributeUsage(System.AttributeTargets.All, AllowMultiple = false)]
public sealed class TestAttribute : Attribute
{
public TestAttribute(int num, string name)
{
Num = num;
Name = name;
}
public int Num { get; private set; }
public string Name { get; private set; }
}
然后注释"advanced"枚举类型:
public enum MyEnum
{
[Test(1, "hi")]
Foo,
[Test(2, "cool")]
Bar,
}
然后为高级枚举创建扩展:
public static class TestExtensions
{
public static int Num(this MyEnum val)
{
int n = 0;
FieldInfo fi = val.GetType().GetField(val.ToString());
TestAttribute[] attrs =
fi.GetCustomAttributes(typeof(TestAttribute),
false) as TestAttribute[];
if (attrs.Length > 0)
{
n = attrs[0].Num;
}
return n;
}
public static string Name(this MyEnum val)
{
string n = "";
FieldInfo fi = val.GetType().GetField(val.ToString());
TestAttribute[] attrs =
fi.GetCustomAttributes(typeof(TestAttribute),
false) as TestAttribute[];
if (attrs.Length > 0)
{
n = attrs[0].Name;
}
return n;
}
public static string Title(this MyEnum val)
{
return Enum.GetName(val.GetType(), val);
}
}
然后使用枚举:
public class Program
{
static void Main(string[] args)
{
Console.WriteLine(MyEnum.Bar.Name());
foreach(MyEnum e in Enum.GetValues(typeof(MyEnum)))
{
EnumTest(e);
}
}
public static void EnumTest(MyEnum e)
{
Console.WriteLine(
String.Format("{0}'s name={1}: num={2}", e.Title(), e.Name(), e.Num()));
}
}