2016-07-06 46 views
0

我想用Interlocked.CompareExchange与从int继承,像这样的枚举类型:如何将ref [enum type]转换为ref 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只引用类型和选择值类型(见here)的作品。由于MyEnum是真正的皮肤下面一个int,我想我应该能够把它作为一个参考INT:

// should call CompareExchange(ref int, int, int) overload 
Interlocked.CompareExchange(ref s_field, (int)MyEnum.B, (int)MyEnum.A); 

然而,这似乎并没有任何工作。我得到以下错误:

Error CS1503: Argument 1: cannot convert from 'ref MyEnum' to 'ref int'

铸造之前,它通过,例如ref (int)s_field,也没有帮助。

我该如何解决这个问题?有没有办法使用CompareExchange和枚举,或者我必须使用整数吗?

+0

是否有你的工作枚举任何具体的原因是什么? “互锁”限于数字在这reguas ...你可以使用常量(我知道,...设计气味,但)? –

+0

@AndreasNiedermair是的,我只是觉得代码看起来更好用枚举。 –

+0

你不能做你想做的事情,因为'Interlocked'没有提供API的'enum'变种。你必须使用'int'。 – GreatAndPowerfulOz

回答

0

我相信这是现在可以用它在.NET的核心引入了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或更高版本。

0

你想使用工会吗?

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"); 
} 

当然,这是有点麻烦......

0

有关评估转换后的价值是什么?

 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"); 
0

也许你可以使用:

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; }