【问题标题】:How to convert an arbitrary object to enum?如何将任意对象转换为枚举?
【发布时间】:2014-02-24 06:41:52
【问题描述】:

我有一个对象。通常是longstring,所以为了简化代码让我们假设一下。

我必须创建一个方法来尝试将此对象转换为提供的枚举。所以:

public object ToEnum(Type enumType, object value)
{
    if(enumType.IsEnum)
    {
        if(Enum.IsDefined(enumType, value))
        {
           var val = Enum.Parse(enumType, (string)value);
           return val;
        }
    }
    return null;
}

使用字符串效果很好。使用数字会导致问题,因为枚举的默认基础类型是int,而不是long,而IsDefined 会抛出ArgumentException

当然,我可以进行许多检查、转换或尝试捕获。

我想要的是为此编写一个干净且小巧的代码。 任何想法如何使它可读和简单?

【问题讨论】:

  • 好吧,我必须动态地做(我不知道编译时枚举的类型)。另外,正如我所说,IsDefined 是不行的,因为它对我来说有点太严格了。
  • 解释-1票是个好习惯。如果问题有问题,请告诉我;-)

标签: c# enums type-conversion


【解决方案1】:

在我看来,您实际上只想处理三种情况:

  • 输入已经是正确的类型
  • 字符串
  • 各种类型的整数

我相信这会满足您对有效输入的要求:

public object ToEnum(Type enumType, object value)
{
    if (value == null)
    {
        throw new ArgumentNullException("value");
    }
    if (enumType == null)
    {
        throw new ArgumentNullException("type");
    }
    if (!enumType.IsEnum)
    {
        return false;
    }
    string valueString = value as string;
    if (valueString != null)
    {
        return Enum.IsDefined(enumType, value) ? Enum.Parse(enumType, valueString) : null;
    }
    if (value.GetType() == enumType)
    {
        return value;
    }
    // This appears to handle longs etc
    return Enum.ToObject(enumType, value);
}

但是,即使对于未定义的值,这也会返回正确类型的值。如果您不希望这样,请将最后一部分更改为:

object candidate = Enum.ToObject(enumType, value);
return Enum.IsDefined(enumType, candidate) ? candidate : null;

另外,如果你传入一个浮点数或类似的东西,这仍然会引发异常。如果您不想要这种行为,则需要拥有一组您确实想要接受的所有类型,并首先检查。

【讨论】:

  • 不出所料,这是一个非常好的答案。谢谢你,乔恩!我错过了这个 ToObject 方法。实际上,可用重载的数量可以处理多个我想避免的ifs。老实说,这是我第 n 次发现(整数)数字的基类会很整洁;-) 再次感谢。
  • @PiotrZierhoffer:如果您使用枚举做了大量工作,您可能会发现我的 Unconstrained Melody 库很方便:code.google.com/p/unconstrained-melody
  • 看起来很有趣,谢谢!正如我从您的页面中看到的,它需要一些后期构建处理,这在 Mono 上可能有点麻烦。但我已经多次遇到这个问题......
  • @PiotrZierhoffer:您只需要对库构建进行后处理 - 然后您应该可以在任何地方使用它。
  • 哦,我明白了。好的!我想我会试一试:)
【解决方案2】:

试试这个

public object ToEnum<T>(object value)
    {
        var type = typeof(T);

        if (type.IsEnum)
        {
            int numberVal;

            if (!int.TryParse(value.ToString(), out numberVal) && value.GetType() != typeof(string))
            {
                return null;
            }

            value = numberVal;

            if (Enum.IsDefined(type, value))
            {
                T result = (T)Enum.Parse(type, value.ToString());
                return result;
            }
        }
        return null;
    }

【讨论】:

  • 实际上需要一些修改才能启用字符串值(即字段名称,而不仅仅是整数值)。并且将 int 转换为 string 到 int 对我来说感觉很糟糕,就像走错了路……但无论如何谢谢:)
猜你喜欢
  • 1970-01-01
  • 2012-08-12
  • 2018-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-09
  • 2015-09-01
  • 2021-05-07
相关资源
最近更新 更多