I would like to know if C# automatically implemented properties, like public static T Prop { get; set; }
, are thread-safe or not. Thanks!
问题:
回答1:
It appears not. This is the decompilation with Reflector:
private static string Test
{
[CompilerGenerated]
get
{
return <Test>k__BackingField;
}
[CompilerGenerated]
set
{
<Test>k__BackingField = value;
}
}
回答2:
Section 10.7.4 of the C# specification states:
When a property is specified as an automatically implemented property, a hidden backing field is automatically available for the property, and the accessors are implemented to read from and write to that backing field. The following example:
public class Point {
public int X { get; set; } // automatically implemented
public int Y { get; set; } // automatically implemented
}
is equivalent to the following declaration:
public class Point {
private int x;
private int y;
public int X { get { return x; } set { x = value; } }
public int Y { get { return y; } set { y = value; } }
}
That's what we promise, and that's what you get. The point of auto properties is to do the most basic, simple, cheap thing; if you want to do something fancier then you should write a "real" property.
回答3:
No. You must wrap them in thread-locking mechanisms.
object _lock = new object();
public static Main(string[] args)
{
lock(_lock)
{
Prop = new T();
}
T val = null;
lock(_lock)
{
val = Prop;
}
}
回答4:
I don't believe so. I believe they are just syntatic sugar for:
private static T _prop;
public static T Prop
{
get { return _prop; }
set { _prop = value; }
}
回答5:
There is no synchronization provided with automatic properties, including static properties.
If you need full thread safety, you'll want to use your own properties with a backing field, and handle the synchronization yourself.
回答6:
For completeness, field-like events do have thread-safety built in, but they are alone in this. Automatically implemented properties do not have any such features. You can, however, do something like:
public static double SomeProp
{ // ### NOT RECOMMENDED ###
[MethodImpl(MethodImplOptions.Synchronized)] get;
[MethodImpl(MethodImplOptions.Synchronized)] set;
}
The problem with this is that it will lock the Type
, which is a bad thing. I would implement my own synchronization for this, personally.
回答7:
No, they not threadsafe. Static properties just as vulnerable as static fields are to concurrency issues.