15

なぜ次のことができないのだろうか:

struct TestStruct
{
    public readonly object TestField;
}

TestStruct ts = new TestStruct {
    /* TestField = "something" // Impossible */
};

オブジェクト初期化子はフィールドの値を設定できるべきではありませんか?

4

8 に答える 8

2

これは不可能です。またはreadonly以外からフィールドを割り当てることができないためです。ConstructorField Initializer

あなたが示すのは実際object initializerです。それは単なるシンタティックシュガーであり、このようなものにまとめられます

TestStruct ts;
TestStruct ts1 = new TestStruct();
ts1.TestField = value;
ts = ts1;

コンパイルできない理由は明らかですか?

于 2013-08-22T15:53:00.057 に答える
1

オブジェクト初期化子は初期化の簡単な方法にすぎないため:

TestStruct ts = new TestStruct {
  TestField = "something";
};

と同じです(コンパイラは上記をこれに変換します):

TestStruct ts = new TestStruct();
ts.TestField = "something";//this is of course not allowed.
于 2013-08-22T15:52:17.817 に答える
-1

readonly フィールドが CollectionBase を拡張する場合、これに対する興味深い「例外」に出くわしました。

コードは次のとおりです。

using System.Collections;

namespace ReadOnly
{
    class Program
    {
        static void Main(string[] args)
        {
            Foo foo1 = new Foo()
            {
                Bar = new Bar()  // Compile error here - readonly property.
                {
                    new Buzz() { Name = "First Buzz" }
                }
            };

            Foo foo2 = new Foo()
            {
                Bar = // No Compile error here.
                {
                    new Buzz { Name = "Second Buzz" }
                }
            };
        }
    }

    class Foo
    {
        public Bar Bar { get; }
    }

    class Bar : CollectionBase
    {
        public int Add(Buzz value)
        {
            return List.Add(value);
        }

        public Buzz this[int index]
        {
            get { return (Buzz)List[index]; }
            set { List[index] = value; }
        }
    }

    class Buzz
    {
        public string Name { get; set; }
    }
}

Foo1 は私が最初にやろうとした方法です (これらのクラスはすべて外部ライブラリから取得したため、最初は Bar が読み取り専用であることを知りませんでした)。コンパイルエラーが発生しました。その後、誤って foo2 のように再入力したところ、機能しました。

dll を逆コンパイルし、Bar が CollectionBase を拡張したことを確認した後、2 番目の構文 (foo2) がコレクションの Add メソッドを呼び出していることに気付きました。したがって、コレクションの場合、読み取り専用のプロパティを設定することはできませんが、オブジェクト初期化子を介して Add メソッドを呼び出すことができます。

于 2016-11-17T16:35:36.627 に答える