C#自动实现的静态属性是否是线程安全的?

Mig*_*elo 23 c# static properties automatic-properties thread-safety

我想知道C#自动实现的属性public static T Prop { get; set; }是否是线程安全的.谢谢!

Eri*_*ert 51

C#规范的第10.7.4节规定:

将属性指定为自动实现的属性时,将为该属性自动提供隐藏的后备字段,并且实现访问器以读取和写入该后备字段.以下示例:

public class Point {
  public int X { get; set; } // automatically implemented
  public int Y { get; set; } // automatically implemented
}
Run Code Online (Sandbox Code Playgroud)

相当于以下声明:

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; } }
}
Run Code Online (Sandbox Code Playgroud)

这就是我们的承诺,这就是你得到的.汽车性能的关键在于做最基本,简单,便宜的事情; 如果你想做更好的事情那么你应该写一个"真正的"财产.

  • 请求您参考实际的C#规范. (7认同)
  • 嗯,这是埃里克·利珀特(Eric Lippert)回答的……:-D (2认同)

que*_*rin 15

看来不是.这是使用Reflector的反编译:

private static string Test
{
    [CompilerGenerated]
    get
    {
        return <Test>k__BackingField;
    }
    [CompilerGenerated]
    set
    {
        <Test>k__BackingField = value;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 正如我在这种情况下理解的那样,"原子"意味着在更新中期无法看到它.例如,`double`不保证原子; 如果你将一个双字段从{x}更改为{y},另一个线程只有在上半部分更新后才能看到它 - 它可能会得到一个**不同的**数字({z}),它从来没有**作为该领域的"真实"价值存在(巨大的腐败问题). (8认同)
  • 规范保证像`Int32`,`float`和引用这样的东西是**原子**.它没有很多关于线程可见性/寄存器缓存等的保证. (3认同)

Amy*_*Amy 6

不可以.您必须将它们包装在螺纹锁定机构中.

object _lock = new object();
public static Main(string[] args)
{
    lock(_lock)
    {
         Prop = new T();
    }


    T val = null;
    lock(_lock)
    {
         val = Prop;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • Prop和T来自这个问题. (4认同)

Ree*_*sey 5

自动属性(包括静态属性)没有提供同步。

如果您需要完整的线程安全,您将需要使用您自己的属性和一个支持字段,并自己处理同步。


Mar*_*ell 5

为了完整起见,类似字段的事件确实具有内置的线程安全性,但它们是唯一的。自动实现的属性没有任何此类功能。但是,您可以执行以下操作:

public static double SomeProp
{   // ### NOT RECOMMENDED ###
    [MethodImpl(MethodImplOptions.Synchronized)] get;
    [MethodImpl(MethodImplOptions.Synchronized)] set;
}
Run Code Online (Sandbox Code Playgroud)

这样做的问题是它会锁定Type,这是一件坏事。我个人会为此实现自己的同步。