1

この答えから出てくると、意味をなさないと思われるいくつかのコードが現れました:

class Program
{
    static void Main(string[] args)
    {
        var t = new Testing
        {
            ListOfStrings =
            { 
                "hello", 
                "goodbye" 
            }
        };

        Console.ReadKey();
    }
}

public class Testing
{
    public List<string> ListOfStrings { get; private set; }

    public Testing()
    {
        ListOfStrings = new List<string>();
    }
}

一見すると、このコードはコンパイルできないと思われるかもしれません。結局のところListOfStrings、プライベート セッターがあるはずであり、この方法で割り当てられるべきではありません。

ただし、このコードは正常にコンパイルおよび実行t.ListOfStringsされ、値が割り当てられています。

このコレクションの初期化でプライベート セッターが無視されるのはなぜですか?

4

2 に答える 2

3

あなたの例では、実際にプロパティを設定していません。

C# は、Add、Remove、Clear などを使用してパブリックに変更できる ICollection を使用していることを認識できるほどスマートです。実行していることは、次のことと同じです。

t.AddRange(new string[] { "hello", "goodbye" });

実際にこれを実行しようとすると、うまくいきません:

var t = new Testing
{
    ListOfStrings = new List<string>(),
};

編集:

コレクションを読み取り専用として公開する方法を知りたい場合は、IEnumerable として公開するだけでこれを行うことができます。

public class Testing
{
    private List<string> _listOfStrings;
    public IEnumerable<string> MyStrings
    {
        get
        {
            foreach (var s in _myStrings)
                yield return s;
        }
    }

    public Testing()
    {
        _listOfStrings = new List<string>();
    }
}

読み取り専用のコレクションを作成することもできますが、それはより混乱を招きます。それを IEnumerable として公開すると、クラスの消費者は項目を追加または削除する機能なしで項目を列挙できます。

于 2013-10-10T20:02:13.560 に答える
1

このコレクションの初期化でプライベート セッターが無視されるのはなぜですか?

そうではありません。このコレクションの初期化構文:

    var t = new Testing
    {
        ListOfStrings =
        { 
            "hello", 
            "goodbye" 
        }
    };

実際には、コンパイラによって次のように変換されます。

var t = new Testing();
t.ListOfStrings.Add("hello");
t.ListOfStrings.Add("goodbye");

ご覧のとおり、ListOfStrings実際には新しい値が割り当てられていません...

于 2013-10-10T20:01:50.977 に答える