【问题标题】:Object & Collection Initializers and Accessors对象和集合初始化器和访问器
【发布时间】:2017-01-14 11:35:14
【问题描述】:

我想从我是 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 的集合,以及 C# 如何设置 coll_ 的值。在Coll 的get 和set 访问器中使用该标识符是否足以让C# 将coll_ 识别为内部存储;或者可能是因为它是相应类型的唯一成员而设置的?

【问题讨论】:

  • 这一行调用 Coll setter Coll = { 1, 2, 3, 4, 5 },
  • @Steve 我也这么认为,但事实并非如此。等一下,用一个活生生的例子更新问题。
  • @Steve 为问题添加了this 现场示例。
  • 集合初始化器被转换为Add 调用。通常你会在示例中看到new List &lt;int&gt; { 1, 2, 3 },但这由两部分组成:new 部分和集合初始值设定项。在这里,您只有集合初始化程序 - newing 已经在 How 的构造函数中完成。您应该会看到对 Coll 的 getter 的调用。
  • @PieterWitvoet 我不知道它会转化为重复的 Add 调用!这很有意义。感谢您的帮助! :)

标签: c# accessor object-initializers collection-initializer


【解决方案1】:
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_ = new ObservableCollection&lt;int&gt;(); 行,程序将因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_ = "";
}

集合初始化器在 C# 语言规范的 §7.6.10.3 中描述

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-04
    • 2018-10-05
    • 2011-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-05
    相关资源
    最近更新 更多