61

我在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; 
        }
    }
}

我哪里错了?

4

7 回答 7

104

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

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

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

如果我统治世界,就不会这样了。当我在 6 月的NDC 2010上见到一些语言设计者(请一起来!)时,我打算尝试说服、贿赂、哄骗,并且通常会惹恼自己,直到他们同意为止。毕竟,这只是一个极薄的功能。

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

// Read-only properties.

...这绝对是错误的。该框架同意我们的观点:

var prop = typeof(Contact).GetProperty("Name");
Console.WriteLine(prop.CanWrite); // Prints True
于 2010-03-19T20:51:36.907 回答
8

该属性在类外是只读的Foo。我认为这就是文章的意思。

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

于 2010-03-19T20:56:07.913 回答
6

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

  • 只读:他们的意思是外面没有人可以直接写,只能读。
  • C# readonly:你只能在构造函数中写入它,然后再也不写了。
于 2010-03-19T20:59:59.870 回答
4

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

对于自动实现的属性,get 和 set 访问器都是必需的

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

没有 set 访问器的属性被认为是只读的

于 2010-03-19T21:54:46.903 回答
2

私有集与readonly.

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

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

于 2010-03-19T20:55:26.447 回答
1

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

'ProjectName.ClassName.Property.get' 必须声明一个主体,因为它没有标记为抽象或外部。自动实现的属性必须同时定义 get 和 set 访问器。

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

于 2013-07-03T17:28:59.557 回答
1

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

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

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

于 2012-10-14T17:45:55.170 回答