只读自动实现的属性是否可能?

发布于 2024-08-25 15:37:56 字数 941 浏览 10 评论 0原文

我在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

掌心的温暖 2024-09-01 15:37:56

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

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

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

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

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

// Read-only properties.

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

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

The answer below was written back in 2010. In C# 6 (released in 2015) you can write read-only automatically-implemented properties:

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

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

// Read-only properties.

... which are definitely wrong. The framework agrees with us:

var prop = typeof(Contact).GetProperty("Name");
Console.WriteLine(prop.CanWrite); // Prints True
‖放下 2024-09-01 15:37:56

该属性在 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.

听,心雨的声音 2024-09-01 15:37:56

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

  • 只读:意味着外部没有人可以直接写入,只能读取。
  • C# readonly:您只能在构造函数中对其进行写入,然后再也不能写入。

It's confusing. You should differentiate read-only to the c# readonly (what the keyword means).

  • read-only: they mean that no one outside can write to it directly, only read.
  • C# readonly: you can only write to it in the constructor, then never more.
绻影浮沉 2024-09-01 15:37:56

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

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

只读属性没有 set 访问器。

没有设置访问器的属性被视为只读

No, it's not possible to make an auto-implemented property readonly. For the page you linked:

with auto-implemented properties, both a get and set accessor are required

A read-only property has NO set accessor.

A property without a set accessor is considered read-only

瞎闹 2024-09-01 15:37:56

私有集与只读不同。

与方法或字段类似,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.

夏夜暖风 2024-09-01 15:37:56

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).

半寸时光 2024-09-01 15:37:56

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

“ProjectName.ClassName.Property.get”必须声明一个主体,因为它未标记为“抽象”或“外部”。自动实现的属性必须定义 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:

'ProjectName.ClassName.Property.get' must declare a body because it is not marked abstract or extern. Automatically implemented properties must define both get and set accessors.

With the sentence begining with 'Automatically' being the part of the error we are concerned with.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文