我生成动态枚举,表示在C#ASP.NET解决方案中来自我的数据库的整数ID。我想要两件事,虽然两者都不可能。
1)我希望.ToString()方法给我“345”,而不是枚举的字符串名称(它表示为字符串的int)。这个问题的每个答案似乎都在添加
[Description="Blah"]
EnumName = 1
在声明之上并使用GetDescription()方法。我不知道如何使用我正在使用的动态代码执行此操作。
2)我宁愿不转换为int来使用它,例如,我宁愿(Enum.Name == 5)。如果这不可能我会演员,但我真的不想使用((int)Enum.Name))。ToString();
以下是动态代码生成:
public static void Main()
{
AppDomain domain = AppDomain.CurrentDomain;
AssemblyName aName = new AssemblyName("DynamicEnums");
AssemblyBuilder ab = domain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Save);
ModuleBuilder mb = ab.DefineDynamicModule(aName.Name, aName.Name + ".dll");
List<Type> types = new List<Type>();
foreach(ReferenceType rt in GetTypes())
{
EnumBuilder eb = mb.DefineEnum(rt.Name, TypeAttributes.Public, typeof(int));
foreach (Reference r in GetReferences(rt.ID))
{
eb.DefineLiteral(NameFix(r.Name), r.ID);
}
types.Add(eb.CreateType());
}
ab.Save(aName.Name + ".dll");
foreach (Type t in types)
{
foreach (object o in Enum.GetValues(t))
{
Console.WriteLine("{0}.{1} = {2}", t, o, ((int) o));
}
Console.WriteLine();
//Console.ReadKey();
}
Console.WriteLine();
Console.WriteLine("Dynamic Enums Built Successfully.");
}
public static string NameFix(string name)
{
//Strip all non alphanumeric characters
string r = Regex.Replace(name, @"[^\w]", "");
//Enums cannot begin with a number
if (Regex.IsMatch(r, @"^\d"))
r = "N" + r;
return r;
}
可能没有办法做我想做的事情,我将被困在使用:
(int)Countries.USA //For int value
((int)Countries.CAN).ToString() //For string representation of int value, ex. "354"
有什么想法吗?
答案 0 :(得分:3)
您是否可以调整类型安全的枚举模式以满足您的需求?
public class MyEnum
{
#region Enum Values
// Pre defined values.
public static readonly MyEnum ValueOne = new MyEnum(0);
public static readonly MyEnum ValueTwo = new MyEnum(1);
// All values in existence.
private static readonly Dictionary<int, MyEnum> existingEnums = new Dictionary<int, MyEnum>{{ValueOne.Value, ValueOne}, {ValueTwo.Value, ValueTwo}};
#endregion
#region Enum Functionality
private readonly int Value;
private MyEnum(int value)
{
Value = value;
}
public static MyEnum GetEnum(int value)
{
// You will probably want to make this thread-safe.
if (!existingEnums.ContainsKey(value)) existingEnums[value] = new MyEnum(value);
return existingEnums[value];
}
public override string ToString()
{
return Value.ToString();
}
#endregion
}
用法:
private void Foo(MyEnum enumVal)
{
return "Enum Value: " + enumVal; // returns "Enum Value: (integer here)
}
或者:
MyEnum.GetValue(2) == MyEnum.GetValue(4); // false
MyEnum.GetValue(3) == MyEnum.GetValue(3); // true
答案 1 :(得分:3)
所以你真的想将Enum
值转换为string
而不是名称?转换为Enum
的基础类型是获取价值的最简单方法。我认为你很难比((int)...)
更短或更简单。
如果您不想“枚举”某些值,或者想要做一些不同的事情,您可以创建自己的YourEnum
类,它基本上内置了强制转换,在需要时进行渲染似乎更容易,更易读
也许你真的想要一些常数。
const string Blah = "345";
修改
我还有另外一个想法,你可以像这样编写Enum
的扩展方法,
public static class MyExtentions
{
public static string ValueString(this Enum e)
{
var ut = Enum.GetUnderlyingType(e.GetType());
var castToString = typeOf(MyExtentions).GetMethod("CastToString");
var gcast = cast.MakeGenericMethod(ut);
var gparams = new object[] {e};
return gcast.Invoke(null, gparams).ToString();
}
public static string CastToString<T>(object o)
{
return ((T)o).ToString();
}
}
使用此功能,您可以在任何ValueString()
实例上调用Enum
并获取值的字符串。它清楚地使用了反射,因此性能不会太惊人,但我认为这不重要。
答案 2 :(得分:2)
当您使用Enum类类型时,如何使用Enum.Format方法。
例如:
enum EnumClassA {One, Two, Three, Four};
...
EnumClassA chosenValue = EnumClassA.Three;
Console.WriteLine("Chosen value is {0}", Enum.Format(typeof(EnumClassA), chosenValue, "d"));
这应该输出:
Chosen value is 2
修改强>
另一种选择是:
EnumClassA.Three.ToString("d"); //Enum.Name.ToString("d")
这也给出字符串值“2”。
**编辑**
当您进行比较以查看您的枚举中是否存在该值时,如何使用返回bool的Enum.IsDefined(enumType,value)?
Console.WriteLine("Does the enumClassA contain {0} result is {1}", 5, Enum.IsDefined(typeof(enumClassA), 5));
这给出了输出:
Does the enumClassA contain 5 result is False
答案 3 :(得分:2)
我意识到这个问题已被标记为已回答,但是使用扩展可能有用吗?
它仍然允许您以这种方式使用生成的枚举。
PS。调用GetString时要小心 - 不要不小心调用ToString!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
namespace ConsoleApplication1
{
public enum YourEnum
{
Apples = 1,
Pears = 2,
}
class Program
{
static void Main(string[] args)
{
foreach (var value in (YourEnum[])Enum.GetValues(typeof(YourEnum)))
{
int v = value.GetValue();
Console.WriteLine("{0} = {1} (int)", value.ToString(), v);
string s = value.GetString();
Console.WriteLine("{0} = {1} (string)", value.ToString(), s);
}
Console.ReadLine();
//Results:
//Apples = 1 (int)
//Apples = 1 (string)
//Pears = 2 (int)
//Pears = 2 (string)
}
}
public static class EnumExtensions
{
public static int GetValue(this Enum value)
{
return Convert.ToInt32(value);
}
public static string GetString(this Enum value)
{
return Convert.ToInt32(value).ToString();
}
}
}