C# 正在分析字符串以匹配枚举值
如果我有一个字符的枚举C# 正在分析字符串以匹配枚举值,c#,enums,C#,Enums,如果我有一个字符的枚举 public enum Action { None, Address = 'A', Amendment = 'C', Normal = 'N' } 解析单个字符串以匹配相应的枚举字符并在未找到时匹配None的最佳方法是什么。TryParse匹配名称而不是值 例如,如果我的字符串是“C”,我会想得到Action.Amendment 提前感谢请投下: Action f = (Action)'C'; 如果您有一个字符串且为正值,则至少可以执行
public enum Action
{
None,
Address = 'A',
Amendment = 'C',
Normal = 'N'
}
解析单个字符串以匹配相应的枚举字符并在未找到时匹配None的最佳方法是什么。TryParse匹配名称而不是值
例如,如果我的字符串是“C”,我会想得到Action.Amendment
提前感谢请投下:
Action f = (Action)'C';
如果您有一个字符串且为正值,则至少可以执行1个字符的操作:
Action f = (Action)"C"[0];
charc='c';//存在价值
var action=Enum.GetValues(typeof(action)).Cast().FirstOrDefault(a=>(char)a==c);
//行动=行动.修正案
以及:
charc='X';//不存在的价值
var action=Enum.GetValues(typeof(action)).Cast().FirstOrDefault(a=>(char)a==c);
//动作=动作。无
枚举是幕后的数字类型。您可以尝试一类公共字符串:
public class Action()
{
public const string A = "Address";
public const string C = "Amendment";
}
如果您想用两种方法来实现,那么您可能需要使用一个双向字典集合。我个人会将它们保留为整数,并使用和一个实用程序类来获取该类型的描述属性。然后,您可以使用不仅仅是一个字符来显示您想要的内容 这方面的一个例子是
/// <summary>
/// Returns the string value defined by the description attribute of the given enum.
/// If no description attribute is available, then it returns the string representation of the enum.
/// </summary>
/// <param name="value">Enum to use</param>
/// <returns>String representation of enum using Description attribute where possible</returns>
public static string StringValueOf(Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes.Length > 0)
{
return attributes[0].Description;
}
else
{
return value.ToString();
}
}
基于@Mr Moose,我想提供我的2美分代码。它包含相同的方法,但也包含相反的方法。因此,在序列化-反序列化的情况下,它可以组合在一起 在代码中包含
EnumExtensions
类:
using System.ComponentModel;
using System.Linq;
using System.Reflection;
public static class EnumExtensions
{
/// <summary>
/// Converts the bare enum value to a string using the <see cref="DescriptionAttribute"/>
/// that was appplied to it.
/// </summary>
/// <typeparam name="TEn"></typeparam>
/// <param name="enumValue"></param>
/// <returns></returns>
public static string ToDescription<TEn>(this TEn enumValue) where TEn : struct
{
FieldInfo fi = enumValue.GetType().GetField(enumValue.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes.Length > 0 ? attributes[0].Description : enumValue.ToString();
}
/// <summary>
/// Does the reverse lookup. If there is an enum member with the string <paramref name="enumString"/>
/// as <see cref="DescriptionAttribute"/> it will be returned, otherwise the fallback value in
/// <paramref name="fallback"/> will be returned.
/// </summary>
/// <typeparam name="TEn">Type of the enum in question.</typeparam>
/// <param name="enumString">String serialization of Description annotated enum.</param>
/// <param name="fallback">Default value to return.</param>
/// <returns>Either the found value or the fallback.</returns>
public static TEn FromDescription<TEn>(this string enumString, TEn fallback = default(TEn)) where TEn : struct
{
if (enumString != null)
{
FieldInfo[] fieldInfo = typeof(TEn).GetFields();
foreach (var fi in fieldInfo)
{
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes.Any(att => att.Description == enumString))
{
object rawConstantValue = fi.GetRawConstantValue();
return (TEn)rawConstantValue;
}
}
}
return fallback;
}
}
像这样使用它:
string v = "<>";
ComparisonOperators x = v.FromDescription(ComparisonOperators.Equal);
string w = x.ToDescription();
Debug.Assert(v==w); //ok
string v=”“;
ComparisonOperators x=v.FromDescription(ComparisonOperators.Equal);
字符串w=x.ToDescription();
Assert(v==w)//好啊
“我有一个字符的枚举”-不,您没有:)您有一个int
s的枚举,其值是使用字符文字指定的。@Porges感谢您的澄清!我认为他想得到操作。例如,使用'X'
的没有任何操作,因为'X'
不是枚举的有效值。@DarinDimitrov是的,我注意到了。这就是为什么我给了你答案这是更干净的,而且“我们不需要LINQ”来解析枚举,我们从2003年开始解析枚举!“omg,ffs@b0rg但是如果没有linq,我想用一行程序来处理返回None
的错误值是不可能的(呵呵,韵)@OskarKjellin一行代码,包含3个扩展方法调用、1个typeof、1个typecast和一个lambda。这是我在linq中遇到的问题-它隐藏了代码的实际用途,更不用说它将生成的可怕的il了。还有通常的猜测游戏“哪种链式方法不支持monad可能是正确的?”“.谢谢,我不知道如何描述贡品。这帮助了我(有一个不同的问题,但仍然…)@DanielGruszczyk-没问题。您也不局限于描述贡品。任何一个都可以用来做这件事。我们使用它来执行一个系统值到另一个系统值的映射(即,枚举值表示一个系统的值,并且我们有几个描述属性用于映射到其他系统,或者更好的描述,或者需要与枚举值耦合的一些其他相关信息)。
public enum Action
{
None,
[DescriptionAttribute("A")]
Address,
[DescriptionAttribute("C")]
Amendment,
[DescriptionAttribute("N")]
Normal
}
using System.ComponentModel;
using System.Linq;
using System.Reflection;
public static class EnumExtensions
{
/// <summary>
/// Converts the bare enum value to a string using the <see cref="DescriptionAttribute"/>
/// that was appplied to it.
/// </summary>
/// <typeparam name="TEn"></typeparam>
/// <param name="enumValue"></param>
/// <returns></returns>
public static string ToDescription<TEn>(this TEn enumValue) where TEn : struct
{
FieldInfo fi = enumValue.GetType().GetField(enumValue.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes.Length > 0 ? attributes[0].Description : enumValue.ToString();
}
/// <summary>
/// Does the reverse lookup. If there is an enum member with the string <paramref name="enumString"/>
/// as <see cref="DescriptionAttribute"/> it will be returned, otherwise the fallback value in
/// <paramref name="fallback"/> will be returned.
/// </summary>
/// <typeparam name="TEn">Type of the enum in question.</typeparam>
/// <param name="enumString">String serialization of Description annotated enum.</param>
/// <param name="fallback">Default value to return.</param>
/// <returns>Either the found value or the fallback.</returns>
public static TEn FromDescription<TEn>(this string enumString, TEn fallback = default(TEn)) where TEn : struct
{
if (enumString != null)
{
FieldInfo[] fieldInfo = typeof(TEn).GetFields();
foreach (var fi in fieldInfo)
{
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes.Any(att => att.Description == enumString))
{
object rawConstantValue = fi.GetRawConstantValue();
return (TEn)rawConstantValue;
}
}
}
return fallback;
}
}
public enum ComparisonOperators
{
[Description("=")]
Equal,
[Description("<>")]
Unequal,
[Description("<")]
LessThan,
[Description("<=")]
LessThanOrEqual,
[Description(">")]
GreaterThan,
[Description(">=")]
GreaterThanOrEqual
}
string v = "<>";
ComparisonOperators x = v.FromDescription(ComparisonOperators.Equal);
string w = x.ToDescription();
Debug.Assert(v==w); //ok