2017-01-14 2 views
1

Я хотел бы начать с того, что я новичок в C#, поэтому аксессоры и инициализаторы объектов - это совершенно новая концепция для меня. Тем не менее, я думаю, что у меня есть ладно ручку на них, за исключением следующего примера действительно путаешь меня:Инициализаторы и аксессоры объектов и коллекции

using System; 
using System.Collections.ObjectModel; 

class How { 
    public ObservableCollection<int> Coll { 
     get { return coll_; } 
     set { 
      Console.WriteLine("Setter for Coll Called!"); 
      coll_.Clear(); 
      foreach (int i in value) 
       coll_.Add(i); 
     } 
    } 

    public string Field { 
     get { return field_; } 
     set { 
      Console.WriteLine("Setter for field called"); 
      field_ = value; 
     } 
    } 

    // To confirm the internal coll_ is actually set 
    public void Test() { 
     foreach(int i in coll_) 
      Console.Write(i + " "); 
    } 

    public How() { 
     coll_ = new ObservableCollection<int>(); 
     field_ = ""; 
    } 

    private ObservableCollection<int> coll_; 
    private string field_; 
} 

public class Test { 
    public static void Main() { 
     var how = new How { 
      Coll = { 1, 2, 3, 4, 5 }, 
      Field = "Test Field", 
     }; 

     Console.Write("Coll: "); 
     foreach (int i in how.Coll) 
      Console.Write(i + " "); 
     Console.WriteLine(); 

     Console.WriteLine("Field: " + how.Field); 


     Console.Write("Internal coll_: "); 
     how.Test(); 
     Console.WriteLine(); 
    } 
} 

Выход выше код (см живой пример here):

Setter for field called 
Coll: 1 2 3 4 5 
Field: Test Field 
Internal coll_: 1 2 3 4 5 

Field работает точно так, как я ожидал, но Coll меня смущает. Установщик до Coll никогда не вызывается, что для меня подразумевает, что инициализаторы коллекции не смешиваются с свойствами (или, по крайней мере, с неавтоматическими свойствами). Однако, если это так, я ожидал ошибку времени компиляции.

Независимо от той части поведения, что меня еще более смущает, так это то, что внутреннее значение coll_ как-то установлено на значение инициализатора.

Мне интересно знать a) почему Coll 's set не вызывается, а также как C# может установить значение coll_. Является ли использование этого идентификатора в get и set accessors для Coll достаточным для C# для идентификации coll_ в качестве внутреннего хранилища; или, может быть, потому, что он установлен, потому что это единственный член соответствующего типа?

+0

Эта строка вызывает набор инструментов Coll = _Coll = {1, 2, 3, 4, 5}, _ – Steve

+0

@Steve Я так же думал, что bu t это не так. Подождите, обновив вопрос с помощью живого примера. –

+0

@Steve Добавил [this] (http://ideone.com/rcYE1Y) живой пример к вопросу. –

ответ

1
var how = new How 
      { 
       Coll = { 1, 2, 3, 4, 5 }, 
       Field = "Test Field", 
      }; 

это синтаксис инициализации объекта для класса How.

Coll = { 1, 2, 3, 4, 5 } является формой коллекторно-itializer синтаксиса, предназначенным для сбора свойств, которые не имеют общественный сеттера (но одинаково хорошо работает с теми, которые имеют сеттера). Эта форма требует для Coll для создания экземпляра (не будет null): попытайтесь прокомментировать coll_ = new ObservableCollection<int>(); строку в конструкторе, и программа выйдет из строя с помощью NullReferenceException.

Coll = { 1, 2, 3, 4, 5 } переводится в неоднократных Coll.Add вызовов:

Coll.Add(1); 
Coll.Add(2); 
Coll.Add(3); 
Coll.Add(4); 
Coll.Add(5); 

, чтобы подтвердить это добавить обработчик событий в How конструктору:

public How() 
{ 
    coll_ = new ObservableCollection<int>(); 

    coll_.CollectionChanged += (o,e) => 
    { Console.WriteLine("New items: {0}", String.Join (",", e.NewItems.OfType<int>())); }; 

    field_ = ""; 
} 

Коллекция Инициализаторы описаны в §7.6.10.3 из C# Спецификация языка

Смежные вопросы