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が何を言っているかに関係なく、同じことではありません:)

私が世界を支配した場合、これは当てはまりません。6月のNDC2010で言語デザイナーの何人かを見たとき(一緒に来てください!)、私は彼らが同意するまで、説得し、賄賂を送り、カジョレし、一般的に自分の迷惑をかけるつもりです。結局のところ、これは1つのウェーハのように薄い機能にすぎません。

その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アクセサーの両方が必要です

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

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

于 2010-03-19T21:54:46.903 に答える
2

プライベートセットはと同じではありませんreadonly

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

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

于 2010-03-19T20:55:26.447 に答える
1

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

C#は、readonlyキーワードを他の目的に使用しません。

VBのReadOnlyキーワードは、プロパティに適用されると異なる意味を持ちます。この場合、それは単にPublicプロパティに割り当てる許容できる方法がないことを意味します(内部的には、バッキングフィールドはもちろん他の内部コードを変更できます)。

于 2012-10-14T17:45:55.170 に答える
1

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

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

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

于 2013-07-03T17:28:59.557 に答える