0

我想检查 Enum 是否存在任何枚举中传递的代码。问题是我使用代码属性定义的枚举如下所示。

public enum TestEnum
    {

        None,

        [Code("FMNG")]
        FunctionsManagement,

        [Code("INST_MAST_MGT")]
        MasterInstManagement
}

[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
    public class CodeAttribute : Attribute
    {
        readonly string _code;
        public string Code
        {
            get
            {
                return _code;
            }
        }
        public CodeAttribute(string code)
        {
            _code = code;
        }
    }

现在,我有可用的字符串(例如“FMNG”),我想用传递的字符串搜索那个枚举,该枚举存在于枚举属性中。

如何使用或传递字符串检查/获取该枚举?我尝试使用,Enum.IsDefined(typeof(ActivityEnum), "FMNG")但它不适用于枚举的属性。

4

5 回答 5

1

这是一个通用函数:

    public static object ToEnum(string codeToFind, Type t)
    {
        foreach (var enumValue in Enum.GetValues(t))
        {
            CodeAttribute[] codes = (CodeAttribute[])(enumValue.GetType().GetField(enumValue.ToString()).
            GetCustomAttributes(typeof(CodeAttribute), false));

            if (codes.Length > 0 && codes[0].Code.Equals(codeToFind, StringComparison.InvariantCultureIgnoreCase) ||
                enumValue.ToString().Equals(codeToFind, StringComparison.InvariantCultureIgnoreCase))
                return enumValue;
        }

        return null;
    }

用法: var test = ToEnum("INST_MAST_MGT", typeof(TestEnum));

上述函数Enum如果找到定义的Code属性或codeToFind参数等于 Enum 的值 ToString 将返回该值,您可以根据需要进行调整。

于 2013-05-21T10:37:36.977 回答
1

完全取消该属性并为代码创建一个静态字典也可能是一个想法:

static Dictionary<string, TestEnum> codeLookup = new Dictionary<string, TestEnum>() { 
                                                     { "FMNG" , TestEnum.FunctionsManagement }, 
                                                     { "INST_MAST_MGT", TestEnum.MasterInsManagement } };

然后就做

bool isDefined = codeLookup.ContainsKey("FMNG");

这可能比每次使用反射来循环属性更快,但这取决于您的需求

于 2013-05-21T11:16:14.970 回答
0
public TestEnum GetEnumByAttributeName(string attributeName)
{
    foreach (var item in Enum.GetNames(typeof(TestEnum)))
    {
        var memInfo = typeof(TestEnum).GetMember(item);
        var attributes = memInfo[0].GetCustomAttributes(typeof(CodeAttribute), false);
        if (attributes.Count()> 0 && ((CodeAttribute)attributes[0]).Code == attributeName)
            return (TestEnum)Enum.Parse(typeof(TestEnum), item);
    }
    return TestEnum.None;
}
于 2013-05-21T10:44:38.950 回答
0

您可以使用此方法:

public static T GetEnumValueByAttributeString<T>(string code) where T : struct
{
  if (!typeof(T).IsEnum)
    throw new ArgumentException("T should be an enum");

  var matches = typeof(T).GetFields().Where(f =>
    ((CodeAttribute[])(f.GetCustomAttributes(typeof(CodeAttribute), false))).Any(c => c.Code == code)
    ).ToList();

  if (matches.Count < 1)
    throw new Exception("No match");
  if (matches.Count > 1)
    throw new Exception("More than one match");

  return (T)(matches[0].GetValue(null));
}

如您所见,它会检查您附带的字符串是否不明确。像这样使用它:

var testEnum = GetEnumValueByAttributeString<TestEnum>("FMNG");

如果性能是一个问题,您可能需要初始化并保留Dictionary<string, T>所有“翻译”,以便快速查找。

于 2013-05-21T11:26:24.520 回答
0

我在下面找到了通用方法:

public static T GetEnumValueFromDescription<T>(string description)
        {
            var type = typeof(T);
            if (!type.IsEnum)
                throw new ArgumentException();

            FieldInfo[] fields = type.GetFields();
            var field = fields.SelectMany(f => f.GetCustomAttributes(
                                typeof(CodeAttribute), false), (
                                    f, a) => new { Field = f, Att = a })
                            .Where(a => ((CodeAttribute)a.Att)
                                .Code == description).SingleOrDefault();
            return field == null ? default(T) : (T)field.Field.GetRawConstantValue();
        }

来源:从描述属性中获取枚举

于 2013-05-21T11:54:27.577 回答