如何使类型明确可转换为任何枚举

时间:2018-11-08 10:13:30

标签: c#

我有

struct MyType
{
   public int value;
}

如何定义explicit运算符,使其可转换为任何enum? “任何”表示存在的任何枚举。

如果它是int而不是包含struct的{​​{1}},则已经可以使用“可转换为任何可能的枚举”功能。例如,我可以始终int(AnyEnum)myType.value。但我希望能够直接进行(SomeOtherEnum)myType.value而无需在内部挖掘(AnyEnum)myType。我的想法自然是,以某种方式利用int会将整个事物视为implicit。但是很遗憾,int不支持泛型,因此我必须为我希望支持的每个枚举定义implicit

如果这涉及对C#7.3的implicit通用约束的某种使用,那就很好。但是,即使有约束Enum,我也无法where T : Enumint强制转换为T。 (“无法将类型(T)value转换为int

一个用例示例:

T

另一个,

if(myValue.something == something)
{
   switch((MyEnum)myValue)
   {
       case MyEnum.A : ...
       case MyEnum.B : ...
   }
}
else if(myValue.something == something)
{
   switch((MyOtherEnum)myValue)
   {
       case MyOtherEnum.A : ...
       case MyOtherEnum.B : ...
   }
}

2 个答案:

答案 0 :(得分:4)

如果您想直接从枚举转换而不必访问结构的“值”成员,可以,下面是一个示例:

static void Main(string[] args)
{
    MyType myType;
    myType.value = 1;
    MyEnum myEnum = (MyEnum) myType;
    Console.WriteLine(myEnum);
    Console.ReadLine();
}

enum MyEnum
{
    a = 0,
    b = 1
}

struct MyType
{
    public int value;

    public static explicit operator MyEnum(MyType myType)
    {
        return (MyEnum)myType.value;
    }
}

输出为:

b

如果您想从任何类型的枚举直接转换为您的结构,我认为那是不可能的,您可以按照其他答案中的建议研究泛型,或者为您的类型编写一些扩展助手:

public static class MyTypeExtensions
{
    public static T ToAnyEnum<T>(this MyType myType)
    {
        return (T)Enum.ToObject(typeof(T), myType.value);
    }
}

然后您可以编写:

MyType myType;
myType.value = 1;
MyEnum myEnum = myType.ToAnyEnum<MyEnum>();
MyOtherEnum myOtherEnum = myType.ToAnyEnum<MyOtherEnum>();

答案 1 :(得分:1)

不可能。您不能为任何枚举类型创建强制转换运算符,只能为具体的枚举类型创建,恐怕您会遇到“麻烦”的事情:

var anyEnum = (AnyEnum)myType.value;

另一种方法可能是使用类似ToEnum方法的方法:

struct MyType
{
    int value;

    public T ToEnum<T>() where T : struct
    {
        return (T)Enum.ToObject(typeof(T), this.value);
    }
}

用法:

var anyEnum = myType.ToEnum<AnyEnum>();

您还可以为您的值类型创建一个显式转换:

public static explicit operator int(MyType myType)
{
    return myType.value;
}

那么您可以做:

var anyEnum = (AnyEnum)(int)myType;

我承认它实际上并没有那么短,但这可以使value成为私有的,或者在转换中进行任何其他自定义逻辑。

个人笔记

我认为这种设计没有多大意义。它只是试图回答原始问题。考虑一下很有趣。