C #: что происходит при назначении авто-свойства? - PullRequest
0 голосов
/ 21 ноября 2018

Я узнал, что в C # есть такая вещь, как autoproperty, которая обычно автоматически генерируется компилятором, если я объявил переменную, такую ​​как: public List myList {get;задавать;}

public class MyClass
{

   private List<int> myList;
   public List<int> MyList
   {
       get
       {
           return this.myList;
       }
       set
       {
           this.myList = value;
       }
   }
}

Это позволяет мне получить доступ к переменной следующим образом:

   List<int> a = myInstance.MyList;

Так что она работает как функция, но вызывается как обычный объект.Но что на самом деле назначено?Назначена ли «глубокая ссылка» на объект myList или в функции get назначено что-то вроде «функтора»?Что я имею в виду, если я буду работать с a, будет ли функция get вызываться снова каждый раз?

Причина, по которой я спрашиваю: если я использую это в многопоточном случае с некоторой блокировкой объектав функции get и set я не хочу обходить блокировку.Так что, если я сначала назначу myList для a, а затем поработаю с ним, он больше не будет заблокирован?Я прав?

Ответы [ 3 ]

0 голосов
/ 21 ноября 2018

Но что на самом деле назначено на a?

Тип a равен List<int>, а списки являются ссылочными типами, поэтому переменная содержит ссылку насписок. C # не лжет вам.Тип переменной - это тип переменной .

, она работает как функция, но вызывается как обычный объект.

Это предложение не имеет смысла и указывает на то, что у вас есть некоторое недопонимание того, как работает C #.«Объекты» - это не вещи, которые «называются», если они не являются делегатами.Похоже, вы путаете свойства, переменные, объекты и делегаты. Узнайте, что это за вещи .Будет сложно добиться успеха в программировании на C #, если вы не знаете правильных имен всех частей.

Я думаю, вы хотели сказать, что свойство - это член, доступ к которому осуществляется следующим образом.поле, но чтение и запись свойства реализованы как вызовы методов доступа к элементам .

Я имею в виду, что если я буду работать с a, будет ли вызвана функция getснова каждый раз?

Вы можете сами ответить на этот вопрос, попробовав его:

myInstance.MyList = new List<int> { 10, 20, 30 };
List<int> a = myInstance.MyList;
myInstance.MyList = new List<int> { 100, 200, 300 };
Console.WriteLine(a[0]);

Если a снова выберет свойство, оно должно быть 100. Если это не так, должно быть 10. Сделайте прогноз о том, что произойдет, а затем попробуйте и посмотрите, были ли вы правы.

Если я использую это в многопоточном случае с некоторой блокировкой объектав функции get и set я не хочу обходить блокировку.Так что, если я сначала назначу MyList на a, а затем поработаю с ним, он больше не будет заблокирован?Я прав?

Да.Я воспользуюсь этой возможностью, чтобы указать, что крайне плохая практика программирования - создавать открытый интерфейс, который предоставляет объект, который должен быть заблокирован .Лучшие варианты:

  • Не пишите многопоточные программы.Правильно понять их очень сложно.
  • Если вам нужно, не пишите многопоточные программы, которые совместно используют память между потоками.
  • Если вам нужно совместно использовать память, используйте коллекции, безопасные для потоков, всегда .
0 голосов
/ 21 ноября 2018

Когда вы присваиваете myInstance.MyList для a, вы вызываете свойство MyList get, которое копирует ссылку myList в a.Если вы затем работаете с a, вы будете работать непосредственно со списком, на который ссылается личный myList.Вы будете только проходить через свойство get, если вы его на самом деле называете.

Это в основном теряет частную природу myList.Если вы хотите заставить вызывающего абонента выполнять функции, которые выполняют такие функции, как блокировка, вам придется написать функции для тех операций, которые вы хотите разрешить, например, добавление в список, без предоставления действительного списка вызывающему.

Нет необходимости делать это в C # для потоковых операций - вы должны использовать Concurrent Collections , которые реализуют эти операции бесплатно.

0 голосов
/ 21 ноября 2018

Свойства просто лучше называются парами функций List<int> getValue() и setValue(List<int> value).Есть некоторые второстепенные свойства:

  • они отображаются при отражении
  • они могут быть объявлены в интерфейсах / абстрактных классах
  • они используются как поля, за исключением редкихпадежи (параметры out и ref)

Но в целом это все, что им нужно.

Свойства автоопределения такие же, как и у ручных, за исключением того, что поле поддержки не имеет имени (выможет использоваться в вашем коде), поэтому существует 0 случайного доступа к полю поддержки.

Одно из самых важных правил со свойствами - не писать поля Backing, особенно в коде класса,И просто нижний корпус не работает.Я потерял счет, как часто я кодировал так быстро, верхний регистр не прилипал.Для надежного именования добавьте подчеркивание к основному полю._MyList и MyList довольно сложно перепутать.MyList и myList легко смешиваются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...