C# 对象&;集合初始值设定项和访问器

C# 对象&;集合初始值设定项和访问器,c#,accessor,object-initializers,collection-initializer,C#,Accessor,Object Initializers,Collection Initializer,首先,我是C#新手,所以访问器和对象初始化器对我来说是一个全新的概念。也就是说,我认为我对这些问题的处理很好,但下面的例子让我很困惑: using System; using System.Collections.ObjectModel; class How { public ObservableCollection<int> Coll { get { return coll_; } set { Console.Wri

首先,我是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();
    }
}
字段
的操作与我预期的完全一样,但是
Coll
让我感到困惑。从不调用
Coll
的setter,这意味着集合初始值设定项不会将will与属性(或至少是非自动属性)混合使用。然而,如果是这样的话,我会预料到一个编译时错误

不管这部分行为如何,让我更加困惑的是,
coll\uz
的内部值以某种方式设置为初始值设定值

我想知道a)为什么不调用
Coll
的集合,以及C#如何设置
Coll
的值。在
Coll
的get和set访问器中使用该标识符是否足以让C#将
Coll
标识为内部存储器;或者因为它是对应类型的唯一成员而被设置

var how = new How 
          {
              Coll = { 1, 2, 3, 4, 5 },
              Field = "Test Field",
          };
这是
How
类的对象初始化语法

Coll={1,2,3,4,5}
是一种集合初始化器语法形式,用于没有公共setter的集合属性(但与具有setter的集合属性同样有效)。此表单要求实例化
Coll
(不为
null
):尝试注释
Coll\uu=new ObservableCollection()构造函数中的行,程序将因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_ = "";
}
public How()
{
coll_=新的ObservableCollection();
集合更改+=(o,e)=>
{Console.WriteLine(“NewItems:{0}”,String.Join(“,”,e.NewItems.OfType());};
字段=”“;
}

集合初始值设定项在C#Language Specification的§7.6.10.3中有描述

这一行调用Coll setter Coll={1,2,3,4,5},@Steve我也这么认为,但事实并非如此。请稍候,用一个实例更新问题。@Steve在问题中添加了实例。集合初始值设定项被转换为
Add
调用。通常您会在示例中看到
newlist{1,2,3}
,但它由两部分组成:
new
部分和集合初始值设定项。这里,您只有集合初始值设定项,
new
ing已经在
How
的构造函数中完成。您应该看到对
Coll
的getter的调用。@PieterWitvoet我不知道它会转换为重复的Add调用!这很有道理。谢谢你的帮助!:)
public How() 
{
    coll_ = new ObservableCollection<int>();

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

    field_ = "";
}