首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C#中将Int转换为泛型可空Enum

在C#中将Int转换为泛型可空Enum
EN

Stack Overflow用户
提问于 2014-08-14 02:03:49
回答 3查看 4.7K关注 0票数 1

我希望将int值转换为使用泛型函数的可空枚举。我认为这会很容易,尤其是关于枚举/整型铸造的所有事情。我发现的最接近的问题是this one,但不幸的是,它不能处理可空的枚举。This question解决了可空枚举的铸造问题,但不使用泛型。

下面是我试图做的一个简单的例子:

代码语言:javascript
复制
public enum SouthParkCharacters
{
    Stan = 0,
    Kyle = 1,
    Eric = 2,
    Kenny = 3
}

public static T CastNullableEnum<T>(int value)
{
    return (T)(object)((int?)value).Value;
}


public static T SomeFunction<T>(this int anyEnumValue)
{
        SouthParkCharacters? spc = SouthParkCharacters.Kenny;

        spc = CastNullableEnum<SouthParkCharacters>(3); //I am working!
        spc = CastNullableEnum<SouthParkCharacters?>(3); //Raise error Specified cast is not valid.

        //This function will be public so I won't have control over the T
        T finalValue = CastNullableEnum<T>(anyEnumValue); //Raise error Specified cast is not valid.

        return finalValue;

}

正如您在最后一个函数中所看到的,非空枚举的强制转换正在工作。问题是,我希望能够从其他泛型函数调用CastNullableEnum,该函数可以使用可空枚举作为泛型类型。

我知道您可以将泛型类型作为可空的泛型CastNullableEnum<T?>传递,但我们是否可以做相反的操作(即将可空的底层类型传递给泛型函数)?

如果不能这样做,那么我猜解决方案将是找到在CastNullableEnum函数中转换枚举值的正确方法。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-08-14 02:56:09

我可能看错了这个问题,买到你可以从空获取底层类型,使用Enum.Parse而不是直接转换。

代码语言:javascript
复制
public T CastNullableEnum<T>(int value) 
{
    var enumType = Nullable.GetUnderlyingType(typeof(T));
    if (Enum.IsDefined(enumType, value)) 
    {
        return (T)(object)Enum.Parse(enumType, value.ToString());
    }
    return default(T);
}

var test1 = CastNullableEnum<SouthParkCharacters?>(3); 
//returns Kenny

var test2 = CastNullableEnum<SouthParkCharacters?>(9); 
// returns null
票数 7
EN

Stack Overflow用户

发布于 2016-04-12 15:19:46

这将起作用:

代码语言:javascript
复制
public static T IntToEnum<T>(object value)
{
    if (value == null)
        return (T)value;

    else if (typeof(T).IsEnum)
        return (T)value;

    else if (Nullable.GetUnderlyingType(typeof(T))?.IsEnum == true)
        return (T)Enum.ToObject(Nullable.GetUnderlyingType(typeof(T)), (int)value);

    throw new Exception(string.Format("Value cannot be converted from {0} to {1}", value.GetType().Name, typeof(T).Name));
}

可用于可空和正则枚举。

代码语言:javascript
复制
public enum Codes
{
    A = 1,
    B = 2,
    C = 3
}

static void Main(string[] args)
{
    Console.WriteLine(IntToEnum<Codes?>(1));
    Console.WriteLine(IntToEnum<Codes?>(null));
    Console.WriteLine(IntToEnum<Codes>(2));
}
票数 3
EN

Stack Overflow用户

发布于 2014-08-14 02:51:59

有趣的问题。此代码的问题是将整数转换为可空枚举,这是不可能的。

代码语言:javascript
复制
  SouthParkCharacters? enumValue = (SouthParkCharacters?)int.MaxValue;
  if (enumValue.HasValue)
     {
         Console.WriteLine("it still has value");
     }

上面的代码正在运行,结果是enumValue仍然是HasValue。

但是无论如何,如果您在编译后查看C#代码,它将如下所示:

代码语言:javascript
复制
public static T CastNullableEnum<T>(int value)
    {
        Type type = typeof(T);
        return (T)((object)value);
    }
    public static T SomeFunction<T>(int anyEnumValue)
    {
        Program.SouthParkCharacters? spc = new Program.SouthParkCharacters?(Program.SouthParkCharacters.Kenny);
        spc = new Program.SouthParkCharacters?(Program.CastNullableEnum<Program.SouthParkCharacters>(new int?(3)));
        spc = Program.CastNullableEnum<Program.SouthParkCharacters?>(new int?(3));
        return Program.CastNullableEnum<T>(new int?(anyEnumValue));
    }

现在,注意

代码语言:javascript
复制
spc = new Program.SouthParkCharacters?(Program.CastNullableEnum<Program.SouthParkCharacters>(new int?(3))); 

这就是未指定的强制转换异常的来源;因为新的SouthParkCharacters?(int值)需要一个整数。

有趣的是,当你立即跑步时,你不会遇到这个问题。有意思,是吧?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25298941

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档