Является ли поле только для чтения в потоке C # безопасным? - PullRequest
22 голосов
/ 27 ноября 2011

Безопасно ли для чтения в C # поле только для чтения?

public class Foo
{
  private readonly int _someField;

  public Foo()
  {
    _someField = 0;
  }

  public Foo(int someField)
  {
    _someField = someField;
  }

  public void SomeMethod()
  {
     doSomething(_someField);
  }
}


Пролистал несколько постов:
- Каковы преимущества маркировки поля как только для чтения в C #? - JaredPar предполагает, что поля, доступные только для чтения, являются неизменяемыми и, следовательно, безопасными.
- Поля только для чтения и безопасность потоков предполагает, что существует некоторый риск, если конструкторы выполняют большую работу.

Итак, если поле только для чтения используется, как в приведенном выше коде, и конструкторы легкие, оно поточно-ориентированное? Что если someField имеет тип ref (например, массив строк)?

Ответы [ 3 ]

22 голосов
/ 27 ноября 2011

Да - ваш код не предоставляет this в любом из конструкторов, поэтому никакой другой код не может "увидеть" объект до того, как он будет полностью создан. Модель памяти .NET (начиная с .NET 2) включает в себя барьер записи в конце каждого конструктора (IIRC - поиск в блоге Джо Даффи для получения более подробной информации), поэтому нет никакого риска, что другой поток увидит «устаревшее» значение, насколько это возможно. насколько я знаю.

Лично я бы все же обычно использовал вместо этого свойство как способ отделить реализацию от API, но с точки зрения безопасности потока это нормально.

3 голосов
/ 27 ноября 2011

Это зависит от того, что находится в поле.

Чтение из поля только для чтения или из любого поля, которое меньше длины слова (включая все ссылочные типы), является атомарной операцией.

Тем не менее, объект внутри поля только для чтения может быть или не быть потокобезопасным.

1 голос
/ 27 ноября 2011

Не смотря на ваш пример, но в целом это зависит от того, к чему применяется только чтение, например, если словарь объявлен только для чтения, вы все равно можете обновить пары значений ключа

...