web-dev-qa-db-ja.com

読み取り専用の自動実装プロパティは可能ですか?

[〜#〜] 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; 
        }
    }
}

私はどこが間違っていますか?

59
abatishchev

以下の回答は2010年に書き戻されました。C#6(2015年にリリース)では、can読み取り専用の自動実装プロパティを書き込みます。

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

あなたは絶対に正しい。適切に読み取り専用の自動実装プロパティは、現在不可能です。セッターをプライベートにすることは、いくつかの本やMSDNが何と言っているかに関係なく、同じことではありません:)

私が世界を支配した場合、これは当てはまりません。 6月の NDC 201 で言語設計者の何人かを見たら(ぜひ一緒に来てください!)納得し、賄,、冗談を言い、一般的に彼らが同意するまで迷惑をかけるつもりです。結局のところ、これはたった1つのwafer-thin機能です。

そのMSDNの記事を見ると、テキスト自体は、読み取り専用の自動プロパティを作成するとは言っていません。自動プロパティを使用して不変タイプを作成し、それは正しいです。唯一の問題のある部分はコメントのコメントです

// Read-only properties.

...これは間違いです。フレームワークは私たちに同意します:

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

プロパティはFooクラスの外部では読み取り専用です。私はそれが記事が得ているものだと思う。

ただし、readonlyキーワードで変数をマークすることとは異なります。

8
kervin

ややこしい。読み取り専用とc#readonly(キーワードの意味)を区別する必要があります。

  • 読み取り専用:外部の誰も直接書き込むことはできず、読み取りのみ可能です。
  • C#readonly:コンストラクターでのみ書き込むことができ、それ以上書き込むことはできません。
6
Samuel Carrijo

いいえ、自動実装プロパティを読み取り専用にすることはできません。リンクしたページの場合:

自動実装プロパティでは、取得アクセサと設定アクセサの両方が必要です

読み取り専用プロパティにはアクセサーが設定されていません。

アクセサが設定されていないプロパティは読み取り専用と見なされます

4
Ben Voigt

C#およびVBのReadOnlyキーワードは、フィールドに適用されたときに同じことを行います。これらは、フィールドが静的初期化中(静的/共有フィールドとしてマークされている場合)またはコンストラクター中にのみ割り当て可能になるようにします。

C#は、読み取り専用キーワードを他の目的に使用しません。

VBのReadOnlyキーワードは、プロパティに適用すると異なる意味を持ちます。この場合、パブリックプロパティ(内部的には、バッキングフィールド)もちろん、他の内部コードを変更できます)。

1
user1739635

プライベートセットはreadonlyとは異なります。

メソッドやフィールドと同様に、privateキーワードは、セッターの可視性をクラス自体のみが利用できるようにします。他のオブジェクトはセッターを使用できませんが、クラス自体のメソッドはそれを自由に呼び出すことができます。したがって、テストコードはコンパイルされ、正常に動作します。

外部オブジェクトにはreadonlyプロパティとして表示されますが、実際の定義では読み取り専用ではありません。

1
womp

readonly自動実装プロパティを作成することはできません。自動実装プロパティを使用してクラスをコンパイルしようとすると、getとsetの両方がない場合、このエラーが発生します。

'ProjectName.ClassName.Property.get'は、抽象または外部としてマークされていないため、ボディを宣言する必要があります。自動的に実装されるプロパティは、getアクセサーとsetアクセサーの両方を定義する必要があります。

「自動」で始まる文は、私たちが関係しているエラーの一部です。

1
Jose Alava