如何将 ref [枚举类型] 转换为 ref int
本文关键字:ref 转换 int 类型 枚举 | 更新日期: 2023-09-27 17:55:51
我想将Interlocked.CompareExchange
与从 int 继承的枚举类型一起使用,如下所示:
public enum MyEnum : int { A, B }
public class MyClass
{
private static readonly MyEnum s_field = MyEnum.A;
public void Foo()
{
if (Interlocked.CompareExchange(ref s_field, MyEnum.B, MyEnum.A) == MyEnum.A)
{
Console.WriteLine("Changed from A to B");
}
}
}
但是,CompareExchange
仅适用于引用类型和选择值类型(请参阅此处)。由于MyEnum
实际上是皮肤下的 int,我想我应该能够将其作为 ref int 传递:
// should call CompareExchange(ref int, int, int) overload
Interlocked.CompareExchange(ref s_field, (int)MyEnum.B, (int)MyEnum.A);
但是,这似乎也不起作用。我收到以下错误:
错误 CS1503:参数 1:无法从"ref MyEnum"转换为"ref int"
在传递之前进行铸造,例如 ref (int)s_field
,也无济于事。
我该如何解决这个问题?有没有办法将CompareExchange
与枚举一起使用,或者我必须改用整数?
你想使用联合吗?
public enum MyEnum : int { A, B }
[StructLayout(LayoutKind.Explicit)]
struct IntEnumUnion
{
[FieldOffset(0)]
public MyEnum Enum;
[FieldOffset(0)]
public int Int;
}
private static IntEnumUnion s_field;
s_field.Enum = MyEnum.A;
if (Interlocked.CompareExchange(ref s_field.Int, (int)MyEnum.B, (int)MyEnum.A)
== (int)MyEnum.A)
{
Console.WriteLine("Changed from A to B");
}
当然,这有点麻烦...
评估后转换值怎么样?
int value = (int)MyEnum.A;
var result = Interlocked.CompareExchange(ref value, (int)MyEnum.A, (int)MyEnum.B);
if((MyEnum)result == MyEnum.A)
System.Console.WriteLine("Changed from A to B");
也许你可以只使用:
static readonly object lockInstance = new object();
public static TSimple CompareExchange<TSimple>(ref TSimple location1, TSimple value, TSimple comparand)
{
lock (lockInstance)
{
var location1Read = location1;
if (EqualityComparer<TSimple>.Default.Equals(location1Read, comparand))
{
// location1 write
location1 = value;
}
return location1Read;
}
}
注意:lock
的事情只会阻止通过此特定方法对location1
进行更改。它无法阻止其他线程在我的方法运行时通过其他方式操作location1
。如果这是一个问题,也许使用 int
并有 public static class MyEnum { public const int A = 0; public const int B = 1; }
.
我相信现在可以通过.NET Core中引入的Unsafe
类来实现这一点。运行以下命令以将包含该类的包安装到您的应用中:
Install-Package System.Runtime.CompilerServices.Unsafe
然后你可以做Interlocked.CE(ref Unsafe.As<MyEnum, int>(ref s_field), (int)MyEnum.B, (int)MyEnum.A)
.请注意,这需要 C# 7 语言支持才能返回 ref,因此需要具有 VS2017 或更高版本。