tags:

views:

1047

answers:

3

I have a bit of my game which looks like this:

public static float Time;

float someValue = 123;
Interlocked.Exchange(ref Time, someValue);

I want to change Time to be a Uint32, however when I try to use UInt32 instead of float for the values it protests that the type must be a reference type. Float is not a reference type, so I know it's technically possible to do this with non reference types, is there any practical way to make this work with UInt32?

A: 

Perhaps use int instead of uint; there are overloads for int. Do you need the extra bit of range? If so, cast / convert as late as possible.

Marc Gravell
Well I never use values less than zero (since it's storing time since the game started), however (2^32)/2 is still a very long game (it's storing milliseconds. I guess for now I'll just use ints and leave it at that.
Martin
+9  A: 

There's an overload for Interlocked.Exchange specifically for float (and others for double, int, long, IntPtr and object). There isn't one for uint, so the compiler reckons the closest match is the generic Interlocked.Exchange<T> - but in that case T has to be a reference type. uint isn't a reference type, so that doesn't work either - hence the error message.

In other words:

As for what to do, the options are any of:

  • Potentially use int instead, as Marc suggests.
  • If you need the extra range, think about using long.
  • Use uint but don't try to write lock-free code

Although obviously Exchange works fine with some specific value types, Microsoft hasn't implemented it for all the primitive types. I can't imagine it would have been hard to do so (they're just bits, after all) but presumably they wanted to keep the overload count down.

Jon Skeet
A: 

You cannot pass a casted expression by reference, you should use a temporary variable:

public static float Time;
float value2 = (float)SomeValue;
Interlocked.Exchange(ref Time, ref value2);
SomeValue = value2;
codymanix
Oh, the cast was just to demonstrate what type that value is, I didn't realise you can't use casts there :O
Martin
the second variable doesn't need to be a reference, look on the MSDN here:http://msdn.microsoft.com/en-us/library/5z8f2s39.aspx
Martin