只读自动实现的属性是否可能?
我在 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;
}
}
}
我哪里错了?
I found a topic on MSDN that talks that yes, this is possible.
I did a test that seems to break this statement:
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;
}
}
}
Where am I wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
下面的答案是在 2010 年写的。在 C# 6(2015 年发布)中,您可以编写只读自动实现的属性:
您完全正确。目前不可能正确地自动实现只读属性。无论一些书籍和 MSDN 可能怎么说,将 setter 设为私有并不是一回事:)
如果我统治世界,情况就不会是这样。当我六月在 NDC 2010 上见到一些语言设计者时(请一起来!)我打算尝试说服、贿赂、哄骗,并且通常会制造麻烦,直到他们同意为止。毕竟,这只是一个晶圆薄的功能。
看看那篇 MSDN 文章,文本本身并没有说它创建了一个只读自动属性。它使用自动属性创建不可变类型,这是正确的。唯一有问题的地方是评论说
……这绝对是错误的。该框架与我们一致:
The answer below was written back in 2010. In C# 6 (released in 2015) you can write read-only automatically-implemented properties:
You're absolutely right. Properly read-only automatically implemented properties are currently impossible. Making the setter private isn't the same thing, regardless of what some books and MSDN might say :)
If I ruled the world, this would not be the case. When I see some of the language designers at NDC 2010 in June (please come along!) I intend to try to persuade, bribe, cajole and generally make a nuisance of myself until they agree. It's just one wafer-thin feature, after all.
Looking at that MSDN article, the text itself doesn't say that it creates a read-only automatic property. It creates an immutable type using an automatic property, and that's correct. The only problematic bits are the comments saying
... which are definitely wrong. The framework agrees with us:
该属性在 Foo 类之外是只读的。我想这就是这篇文章的目的。
但这与使用 readonly 关键字标记变量不同。
The property is read-only outside the
Foo
class. I think that's what article is getting at.But it's not the same as marking a variable with the
readonly
keyword.这很令人困惑。您应该区分只读和 c#
readonly
(关键字的含义)。readonly
:您只能在构造函数中对其进行写入,然后再也不能写入。It's confusing. You should differentiate read-only to the c#
readonly
(what the keyword means).readonly
: you can only write to it in the constructor, then never more.不,不可能将自动实现的属性设置为只读。对于您链接的页面:
只读属性没有 set 访问器。
No, it's not possible to make an auto-implemented property readonly. For the page you linked:
A read-only property has NO set accessor.
私有集与只读不同。
与方法或字段类似,
private
关键字使 setter 的可见性仅对类本身可用。其他对象不能使用setter,但类本身的方法可以自由调用它。因此,您的测试代码可以编译并正常工作。对于外部对象来说,它显示为只读属性,但在真正的定义中它不是只读的。
Private set is not the same as
readonly
.Similar to methods or fields, the
private
keyword makes the visibility of the setter available to only the class itself. Other objects cannot use the setter, but methods of the class itself can call it freely. Hence your test code compiles and works fine.It appears to external objects as a
readonly
property, but it isn't read-only in the true definition.C# 和 VB 中的 ReadOnly 关键字在应用于字段时执行相同的操作。他们使得该字段只能在静态初始化期间(如果它被标记为静态/共享字段)或在构造函数期间分配。
C# 不会将 readonly 关键字用于其他用途。
VB 中的 ReadOnly 关键字在应用于属性时具有不同的含义。在这种情况下,它仅仅意味着没有可接受的方式来分配公共属性(当然,在内部,支持字段可以修改其他内部代码)。
The ReadOnly keyword, in C# and VB, do the same thing when applied to a field. They make it so that field is only assignable during static initialization (if it is marked as a static/shared field) or during the constructor.
C# does not utilize the readonly keyword for anything else.
The ReadOnly keyword in VB takes on a different meaning when applied to a Property. In this case, it simply means that there is no acceptable way to assign to the Public property (internally, the backing field can be modified other internal code, of course).
无法创建
readonly
自动实现的属性。如果您尝试编译具有自动实现属性的类,如果它没有 get 和 set,您将收到此错误:以“自动”开头的句子是我们所关心的错误的一部分。
It is not possible to create a
readonly
auto-implemented property. If you try to compile a class with an auto-implemented property you will get this error if it doesn't have both get and set:With the sentence begining with 'Automatically' being the part of the error we are concerned with.