我有
struct MyType
{
public int value;
}
如何定义一个explicit
运算符,使其可投射到任何enum
?"any"是指存在的任何枚举。
如果是int
而不是包含int
的struct
,则"可转换为任何可能的枚举"函数已经是可能的。例如,我总是可以(AnyEnum)myType.value
、(SomeOtherEnum)myType.value
。但我希望能够直接做(AnyEnum)myType
,而不需要在里面挖int
。我的想法很自然,以某种方式使用implicit
,这将把整个事情视为int
。但不幸的是,implicit
不支持泛型,所以我必须为我希望支持的每个枚举定义implicit
。
如果这涉及到C#7.3的Enum
通用约束的一些使用,那也没关系。但似乎即使有约束where T : Enum
,我也不能通过(T)value
将int
转换为T
。("无法将类型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 : ...
}
}
另一个,
if(myValue.ValidInEnum<MyEnum>(out MyEnum validEnum)) //converted from inside with some additional logic
{
switch(validEnum)
{
case MyEnum.A : ...
case MyEnum.B : ...
}
}
如果你想直接从枚举转换,而不必访问结构的"value"成员,是的,这是可能的,这里有一个例子:
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>();
这是不可能的。你不能为任何枚举类型创建强制转换运算符,只能为具体的枚举类型创建。恐怕你会经历这样做的"大麻烦":
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
私有化,或者在转换中执行任何其他自定义逻辑。
个人笔记
我认为这种设计没有多大意义。它只是试图回答最初的问题。想想就很有趣。