2016-07-06 49 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; }