C# 将对象转换为枚举

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11982918/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 19:57:26  来源:igfitidea点击:

C# Casting with objects to Enums

c#c#-4.0enums

提问by sweetfa

This question relates to casting of enums within generic methods

这个问题与通用方法中的枚举转换有关

Given an enum

给定一个枚举

public enum Crustaceans
{
    Frog = 1,
    Toad = 4
}

I can create an instance of my enum simply enough

我可以简单地创建我的枚举实例

short val = 4;
Crustaceans crusty = (Crustaceans) val;

However, if

然而,如果

short val = 4;
object obj = (object) val;
Crustaceans crusty = (Crustaceans)obj;

a runtime exception is thrown attempting to perform the initialisation of crusty.

尝试执行硬皮的初始化时抛出运行时异常。

Can anyone explain why this is happening, and why it is not legal to do such a thing.

谁能解释为什么会发生这种情况,以及为什么这样做是不合法的。

Not that I really wanted to do this, but I cam across an issue when trying to get something similar happening with generics and effectively that is what is happening under the covers. i.e.

并不是说我真的想这样做,但是我在尝试使用泛型实现类似的事情时遇到了一个问题,实际上这就是幕后发生的事情。IE

public T dosomething<T>(short val) where T : new()
{
    T result = (T)(object) val;
    return result;
}

So what I am attempting to do is have a generic function that works with enums and non-enums (not so critical-but would be nice) that can be set to a short value without throwing an exception and actually initialising the correct enum value.

所以我试图做的是有一个通用函数,它可以与枚举和非枚举一起使用(不是那么重要 - 但会很好),可以设置为一个短值而不抛出异常并实际初始化正确的枚举值。

采纳答案by Tigran

Something like this probablywill help you:

像这样的事情可能会帮助你:

public T dosomething<T>(object o)
{
   T enumVal= (T)Enum.Parse(typeof(T), o.ToString());
   return enumVal;
}

But this will work onlywith enums, for clear reason of using Enum.Parse(..)

但这仅适用于枚举,因为使用的明确原因Enum.Parse(..)

And use this like, for example:

并使用它,例如:

object o = 4;
dosomething<Crustaceans>(o);

That will return Toadin yourcase.

这将Toad您的情况下返回。

回答by Tal Segal

There are cases when you can not use Generics (like in a WPF Converter when you get the value as an object). In this case you can not cast to intbecause the enum type may not be an int. This is a general way to do it without Generics. The Example is given inside a WPF Converter, but the code inside is general:

在某些情况下,您不能使用泛型(例如在 WPF 转换器中,当您将值作为 时object)。在这种情况下,您不能强制转换为,int因为枚举类型可能不是int. 这是没有泛型的通用方法。该示例在 WPF 转换器中给出,但里面的代码是通用的:

using System;
using System.Windows;
using System.Windows.Data;

.
.
.

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    var enumType = value.GetType();
    var underlyingType = Enum.GetUnderlyingType(enumType);
    var numericValue = System.Convert.ChangeType(value, underlyingType);
    return numericValue;
}

回答by Evgeniy Miroshnichenko

By default enum digit values have type = int. In your code you want to cast value that have short type to enum type. For that, you have to set short type to your enum values. This will work:

默认情况下,枚举数字值具有 type = int。在您的代码中,您希望将具有短类型的值转换为枚举类型。为此,您必须将短类型设置为您的枚举值。这将起作用:

public enum Crustaceans : short // <--
{
    Frog = 1,
    Toad = 4
}

short  @short = 1;
object @object = @short;

var @enum = (Crustaceans)@object; // @enum = Crustaceans.Frog   

if you don't want to change default enum values type

如果您不想更改默认枚举值类型

public enum Crustaceans
{
    Frog = 1,
    Toad = 4
}

object @object = Crustaceans.Frog;

var @enum = (Crustaceans)@object; // @enum = Crustaceans.Frog

or

或者

public enum Crustaceans
{
    Frog = 1,
    Toad = 4
}

int @integer= 1;

var @enum = (Crustaceans)@integer; // @enum = Crustaceans.Frog

回答by hazzik

In case of integral types boxed as objects the correct way to do the conversion is using Enum.ToObjectmethod:

如果整数类型装箱为对象,正确的转换方法是使用Enum.ToObject方法:

public T Convert<T>(object o)
{
   T enumVal= (T)Enum.ToObject(typeof(T), o);
   return enumVal;
}