C#对象初始化只读集合属性

时间:2011-04-13 08:17:28

标签: c# c#-4.0 c#-3.0

对于我的生活,我无法弄清楚下面的C#代码示例中发生了什么。测试类的集合(List)属性设置为只读,但我可以在对象初始值设定项中看似分配给它。

**编辑:修正了List'getter'的问题

using System;
using System.Collections.Generic;
using NUnit.Framework;

namespace WF4.UnitTest
{
    public class MyClass
    {
        private List<string> _strCol = new List<string> {"test1"};

        public List<string> StringCollection 
        {
            get
            {
                return _strCol;
            }
        }
    }

    [TestFixture]
    public class UnitTests
    {
        [Test]
        public void MyTest()
        {
            MyClass c = new MyClass
            {
                // huh?  this property is read only!
                StringCollection = { "test2", "test3" }
            };

            // none of these things compile (as I wouldn't expect them to)
            //c.StringCollection = { "test1", "test2" };
            //c.StringCollection = new Collection<string>();

            // 'test1', 'test2', 'test3' is output
            foreach (string s in c.StringCollection) Console.WriteLine(s);
        }
    }
}

4 个答案:

答案 0 :(得分:25)

此:

MyClass c = new MyClass
{
    StringCollection = { "test2", "test3" }
};

被翻译成:

MyClass tmp = new MyClass();
tmp.StringCollection.Add("test2");
tmp.StringCollection.Add("test3");
MyClass c = tmp;

它永远不会试图调用一个setter - 它只是在调用 getter 的结果上调用Add。请注意,它也不是清除原始集合。

这在C#4规范的第7.6.10.3节中有更详细的描述。

编辑:作为一个兴趣点,我有点惊讶于它两次调用吸气剂。我希望它可以调用getter一次,然后再调用Add两次......规范中包含一个演示该示例的示例。

答案 1 :(得分:13)

你没有打电话给二传手;你基本上每次调用c.StringCollection.Add(...)(对于“test2”和“test3”) - 它是集合初始化器。要将它作为属性赋值,它将是:

// this WON'T work, as we can't assign to the property (no setter)
MyClass c = new MyClass
{
    StringCollection = new StringCollection { "test2", "test3" }
};

答案 2 :(得分:0)

我认为,只读,你不能做

c.StringCollection = new List<string>();

但您可以将项目分配给列表...
我错了吗?

答案 3 :(得分:-1)

StringCollection属性没有setter,所以除非你添加一个,否则你无法修改它的值。