是否可以使用只读自动实现属性?

时间:2010-03-19 20:50:44

标签: c# .net properties msdn readonly

我在MSDN上找到了一个主题,说明是的,这是可能的。

我做了一个似乎打破了这个陈述的测试:

using System;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Foo f = new Foo("1");
            Console.WriteLine(f.Bar); // prints 1
            f.Test("2");
            Console.WriteLine(f.Bar);// successfully prints 2
        }
    }

    class Foo
    {
        public Foo(string b)
        {
            this.Bar = b;
        }

        public string Bar { get; private set; }

        public void Test(string b)
        {
            // this would be impossible for readonly field!
            // next error would be occur: CS0191 or CS0191
            // A readonly field cannot be assigned to (except in a constructor or a variable initializer)
            this.Bar = b; 
        }
    }
}

我哪里错了?

7 个答案:

答案 0 :(得分:98)

下面的答案是在2010年写的。在C#6(2015年发布)中,可以编写只读自动实现的属性:

// This can only be assigned to in a constructor
public int Foo { get; }

你是对的。目前不可能正确地执行只读自动实现的属性。无论某些书和MSDN可能会说什么,将setter设为私有都不是一回事:)

如果我统治世界,情况就不是这样了。当我在6月NDC 2010看到一些语言设计师时(请过来!)我打算试图说服,贿赂,哄骗,并且一般会对自己造成滋扰,直到他们同意为止。毕竟,这只是一个 wafer-thin 功能。

查看该MSDN文章,该文本本身并未说明它创建了一个只读的自动属性。它使用自动属性创建一个不可变类型,这是正确的。唯一有问题的是评论说

// Read-only properties.

......这绝对是错的。该框架与我们一致:

var prop = typeof(Contact).GetProperty("Name");
Console.WriteLine(prop.CanWrite); // Prints True

答案 1 :(得分:8)

该属性在Foo类之外是只读的。我认为这就是文章的内容。

但它与使用readonly关键字标记变量不同。

答案 2 :(得分:6)

令人困惑。您应该将只读区分为c#readonly(关键字的含义)。

  • 只读:它们意味着外面没有人可以直接写入,只能读取。
  • C#readonly:你只能在构造函数中写入它,然后才能写更多。

答案 3 :(得分:4)

不,不可能只读取自动实现的属性。对于您链接的页面:

  

使用自动实现的属性,需要get和set访问器

只读属性没有设置访问者。

  

A property without a set accessor is considered read-only

答案 4 :(得分:1)

私人套装与readonly不同。

与方法或字段类似,private关键字使得setter的可见性仅对类本身可用。其他对象不能使用setter,但类本身的方法可以自由调用它。因此,您的测试代码可以编译并正常工作。

外部对象看起来像readonly属性,但它在真正的定义中不是只读的。

答案 5 :(得分:1)

在C#和VB中,ReadOnly关键字在应用于字段时执行相同的操作。它们使得字段只能在静态初始化期间(如果它被标记为静态/共享字段)或在构造函数期间分配。

C#不会将readonly关键字用于其他任何内容。

VB中的ReadOnly关键字在应用于Property时具有不同的含义。在这种情况下,它只是意味着没有可接受的方式来分配公共属性(在内部,支持字段可以修改其他内部代码,当然)。

答案 6 :(得分:1)

无法创建readonly自动实现的属性。如果您尝试使用自动实现的属性编译一个类,如果它没有get和set,则会出现此错误:

  

'ProjectName.ClassName.Property.get'必须声明一个正文,因为它没有标记为abstract或extern。自动实现的属性必须定义get和set访问器。

句子以“自动”开头是我们所关注的错误的一部分。