动态生成时的自定义 C# Enum ToString()
我在 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"
有什么想法吗?
I generate dynamic enums that represent integer IDs from my database in a C# ASP.NET solution. I would like two things, although neither may be possible.
1) I want the .ToString() method to give me "345" for example, not the string name of the enum (the int it represents as a string). Every answer to this question seems to be adding
[Description="Blah"]
EnumName = 1
above the declaration and using a GetDescription() method. I have no idea how to do this with the dynamic code that I am using.
2) I'd rather not cast to an int to use it as such, I'd rather (Enum.Name == 5) for example. If this isn't possible I'll cast, but I really don't want to use ((int)Enum.Name)).ToString();
Here's the dynamic code generation:
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;
}
There may just be no way to do what I want to do, and I'll be stuck using:
(int)Countries.USA //For int value
((int)Countries.CAN).ToString() //For string representation of int value, ex. "354"
Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我意识到该问题已被标记为已回答,但也许使用扩展可能有用?
它仍然允许您以这种方式使用生成的枚举。
附:调用 GetString 时要小心 - 不要意外地调用 ToString!
I realise that the question has been marked as answered, but perhaps using an extension might be useful?
It still allows you to use your generated enums this way.
ps. Take care when calling GetString - don't accidentally call ToString instead!
您可以调整类型安全的枚举模式来满足您的需要吗?
用法:
或:
Could you adapt the type-safe enum pattern to do what you need?
Usage:
Or:
那么您实际上想要将
Enum
值转换为string
而不是名称?转换为Enum
的基础类型是获取值的最简单方法。我认为您将很难找到比((int)...)
更短或更简单的内容。如果您不想“枚举”某些值,或者想做一些不同的事情,您可以创建自己的
YourEnum
类,它基本上内置了强制转换,在需要时进行强制转换似乎更容易且更具可读性。也许您实际上想要一些常量。
编辑
我有另一个想法,你可以为
Enum
编写一个扩展方法,如下所示,}
有了这个,你可以在任何<上调用
ValueString()
code>Enum 实例并获取值的字符串。它显然使用了反射,因此性能不会令人惊叹,但我认为这对您的情况并不重要。So you actually want to convert the
Enum
value to astring
not the name? Casting to theEnum
's underlying type is the simplest way to get the value out. I think you will struggle to get anything shorter or simpler than((int)...)
.If you don't want to "enumerate" some values, or want to do somthing different you could make your own class of
YourEnum
which basically has the cast built in, casting when required seems easier and more readable.Perhaps you actually want some constants.
EDIT
I had another idea, you could write an extension method for
Enum
like this,}
With this you can call
ValueString()
on anyEnum
instance and get a string of the value. It clearly used reflection so the performance won't be amazing but I don't think that matters in your case.当您使用 Enum 类类型时,如何使用 Enum.Format 方法。
例如:
这应该给出一个输出:
edit
另一种选择是:
这也给出了字符串值“2”。
** 编辑 **
当您进行比较以查看枚举中是否存在该值时,如何使用返回 bool 的 Enum.IsDefined(enumType, value) ?
输出为:
As you're using the Enum class type, how about using the Enum.Format method.
For example:
This should give an output of:
edit
Another option would be:
This also gives a string value of "2".
** edit **
As you're doing comparisons to see if the value exists within your enums how about using Enum.IsDefined(enumType, value) which returns a bool?
This gives an output of: