I want to use Interlocked.CompareExchange
with an enum type that inherits from int, like so:
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");
}
}
}
However, CompareExchange
only works with reference types and select value types (see here). Since a MyEnum
is really an int underneath the skin, I thought I should be able to pass it as a ref int:
// should call CompareExchange(ref int, int, int) overload
Interlocked.CompareExchange(ref s_field, (int)MyEnum.B, (int)MyEnum.A);
However, this doesn't seem to work either. I get the following error:
Error CS1503: Argument 1: cannot convert from 'ref MyEnum' to 'ref int'
Casting before passing it in, e.g. ref (int)s_field
, doesn't help either.
How can I fix this? Is there any way to use CompareExchange
with enums, or must I use ints instead?
I believe this is now possible with the Unsafe
class which was introduced in .NET Core. Run this to install the package containing the class into your app:
Install-Package System.Runtime.CompilerServices.Unsafe
In .NET 5+ this is built-in already.
Then you can do:
Interlocked.CompareExchange(ref Unsafe.As<MyEnum, int>(ref s_field), (int)MyEnum.B, (int)MyEnum.A)
Note that this requires C# 7 language support for ref returns, so you need to have VS2017 or later.