简体   繁体   English

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

[英]Is read-only auto-implemented property possible?

I found a topic on MSDN that talks that yes, this is possible. 我在MSDN上发现了一个话题,是的,这是可能的。

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? 我哪里错了?

The answer below was written back in 2010. In C# 6 (released in 2015) you can write read-only automatically-implemented properties: 下面的答案是在2010年写的。在C#6(2015年发布)中,您可以编写只读自动实现的属性:

// 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 :) 让setter私有不是一回事,不管有些书和MSDN可能会说:)

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. 当我在6月看到NDC 2010的一些语言设计师时(请一起来!)我打算试图说服,贿赂,哄骗,并且一般会对自己造成麻烦,直到他们同意为止。 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. 看一下那篇MSDN文章,文本本身并没有说它创建了一个只读的自动属性。 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

The property is read-only outside the Foo class. 该属性在Foo类之外是只读的。 I think that's what article is getting at. 我认为那是文章的内容。

But it's not the same as marking a variable with the readonly keyword. 但它与使用readonly关键字标记变量不同。

It's confusing. 这令人困惑。 You should differentiate read-only to the c# readonly (what the keyword means). 您应该将readonly c# readonly (关键字的含义)。

  • 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. C# readonly :你只能在构造函数中写入它,然后永远不会更多。

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 使用自动实现的属性,需要get和set访问器

A read-only property has NO set accessor. 只读属性具有NO set访问器。

A property without a set accessor is considered read-only 没有set访问器的属性被认为是只读的

The ReadOnly keyword, in C# and VB, do the same thing when applied to a field. 在C#和VB中,ReadOnly关键字在应用于字段时执行相同的操作。 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. C#不会将readonly关键字用于其他任何事情。

The ReadOnly keyword in VB takes on a different meaning when applied to a Property. VB中的ReadOnly关键字在应用于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). 在这种情况下,它只是意味着没有可接受的方式来分配公共属性(在内部,支持字段可以修改其他内部代码,当然)。

It is not possible to create a readonly auto-implemented property. 无法创建readonly自动实现的属性。 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: 如果您尝试使用自动实现的属性编译一个类,如果它没有get和set,则会出现此错误:

'ProjectName.ClassName.Property.get' must declare a body because it is not marked abstract or extern. 'ProjectName.ClassName.Property.get'必须声明一个body,因为它没有标记为abstract或extern。 Automatically implemented properties must define both get and set accessors. 自动实现的属性必须定义get和set访问器。

With the sentence begining with 'Automatically' being the part of the error we are concerned with. 句子以“自动”开头是我们关注的错误的一部分。

Private set is not the same as readonly . 私人套装与readonly

Similar to methods or fields, the private keyword makes the visibility of the setter available to only the class itself. 与方法或字段类似, private关键字使setter的可见性仅对类本身可用。 Other objects cannot use the setter, but methods of the class itself can call it freely. 其他对象不能使用setter,但类本身的方法可以自由调用它。 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. 外部对象看起来是一个readonly属性,但它在真正的定义中不是只读的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM