Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 正在分析字符串以匹配枚举值_C#_Enums - Fatal编程技术网

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