gpt4 book ai didi

c# - 无论 C# 中的基础类型如何,System.Enum 值的一般处理

转载 作者:太空狗 更新时间:2023-10-30 01:26:05 25 4
gpt4 key购买 nike

我实现了一个将两个枚举值作为参数的方法:

void HandleEnumValue( System.Enum v, System.Enum bits )

两个参数的实际枚举类型不一定相同..

在这个方法中,我假设枚举的底层类型是 int。现在第一次使用具有的枚举值调用此方法long 是基础类型,并且该方法现在会抛出异常。

我想增强该方法,使其可以采用任何枚举值,无论的基础类型。我有一个实现,但我不喜欢非常喜欢。

不知是否有更通用/可维护的解决方案?

唉,我不能使用泛型类型参数,因为这会引入一个库中的重大变化,以及对我的方法的无数次调用必须更换。

这是代码,以及我不太好的解决方案:

using System;

[Flags()] public enum ByteEnum : byte { One = 1, SomeByte = 0x42 }
[Flags()] public enum ShortEnum: short{ One = 1, SomeShort = 0x4223 }
[Flags()] public enum IntEnum : int { One = 1, SomeInt = 0x42230815 }
[Flags()] public enum LongEnum : long { One = 1, SomeLong = 0x4223081547112012L }

public class Program
{
public static void Main()
{
HandleEnumValue( ByteEnum.SomeByte, ByteEnum.One ) ;
HandleEnumValue( ShortEnum.SomeShort, ShortEnum.One ) ;
HandleEnumValue( IntEnum.SomeInt, IntEnum.One ) ;
HandleEnumValue( LongEnum.SomeLong, LongEnum.One ) ;

// will throw InvalidCastException: HandleEnumValueOriginal( ByteEnum.SomeByte, ByteEnum.One ) ;
// will throw InvalidCastException: HandleEnumValueOriginal( ShortEnum.SomeShort, ShortEnum.One ) ;
HandleEnumValueOriginal( IntEnum.SomeInt, IntEnum.One ) ;
// will throw InvalidCastException: HandleEnumValueOriginal( LongEnum.SomeLong, LongEnum.One ) ;
}

// new implementation, that I dislike.
static void HandleEnumValue( System.Enum v, System.Enum bits )
{
// assert underlying types of v and bits are equal
if ( v.GetTypeCode() != bits.GetTypeCode() ) throw new Exception( "enum type code mismatch" ) ;

bool hasBitsSet = false ; // won't compile: bool hasBitsSet = ( ( v & bits ) == bits ) ;
long lvalue = 0L ; // will throw : lvalue = (long)(object)v

switch ( v.GetTypeCode() )
{
case TypeCode.Byte :
hasBitsSet = ( ( (byte)(object)v & (byte)(object)bits ) == (byte)(object)bits ) ;
lvalue = (long)(byte)(object)v ;
break ;
case TypeCode.Int16 :
hasBitsSet = ( ( (short)(object)v & (short)(object)bits ) == (short)(object)bits ) ;
lvalue = (long)(short)(object)v ;
break ;
case TypeCode.Int32 :
hasBitsSet = ( ( (int)(object)v & (int)(object)bits ) == (int)(object)bits ) ;
lvalue = (long)(int)(object)v ;
break ;
case TypeCode.Int64 :
hasBitsSet = ( ( (long)(object)v & (long)(object)bits ) == (long)(object)bits ) ;
lvalue = (long)(object)v ;
break ;
}

Console.WriteLine( "(new) enum value = " + v.ToString() ) ;
Console.WriteLine( "(new) number value = " + lvalue.ToString() ) ;
Console.WriteLine( "(new) has bits set = " + hasBitsSet.ToString() ) ;

// further processing ...
}

// original implementation, that doesn't work anymore
static void HandleEnumValueOriginal( System.Enum v, System.Enum bits )
{
int lvalue = (int)(object)v ;
bool hasBitsSet = ( ( (int)(object)v & (int)(object)bits ) == (int)(object)bits ) ;
Console.WriteLine( "(original) enum value = " + v.ToString() ) ;
Console.WriteLine( "(original) number value = " + lvalue.ToString() ) ;
Console.WriteLine( "(original) has bits set = " + hasBitsSet.ToString() ) ;
// further processing ...
}

}

最佳答案

在 .NET 4 中,有一个添加的方法几乎可以满足您的需求:Enum.HasFlag .

不幸的是,如果实际枚举类型不同,此方法将抛出。它的实现非常简单,无需枚举类型检查或如果您使用的是旧版本的框架:

static void HandleEnumValue(Enum v, Enum bits) {
ulong enumValue = ToUInt64(v);
ulong bitsValue = ToUInt64(bits);
bool hasBitsSet = (enumValue & bitsValue) == bitsValue;
Console.WriteLine("enum value = " + v);
Console.WriteLine("number value = " + bits);
Console.WriteLine("has bits set = " + hasBitsSet);
}

internal static ulong ToUInt64(Enum value) {
switch (Convert.GetTypeCode(value)) {
case TypeCode.SByte:
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
return (ulong) Convert.ToInt64(value);
case TypeCode.Byte:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.UInt64:
return Convert.ToUInt64(value);
default:
throw new ArgumentOutOfRangeException("value");
}
}

此方法将处理任何类型的枚举和任何基础类型,即使它们不同。

关于c# - 无论 C# 中的基础类型如何,System.Enum 值的一般处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5685843/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com