3

このサンプルコードがあります。私がやりたいのは、「Nums」値が「AddNum」メソッドを使用してのみ書き込まれるようにすることです。

namespace ConsoleApplication1
{
    public class Person
    {
        string myName = "N/A";
        int myAge = 0;
        List<int> _nums = new List<int>();

        public List<int> Nums
        {
            get
            {
                return _nums;
            }
        }

        public void AddNum(int NumToAdd)
        {

            _nums.Add(NumToAdd);
        }

        public string Name { get; set; }
        public int Age { get; set; }
    }
}

どういうわけか、AsReadOnly() と readonly キーワードに関して多くのことを試しましたが、やりたいことを実行できないようです。

プロパティにアクセスするために必要なコードのサンプルを次に示します。

Person p1 = new Person();
p1.Nums.Add(25); //access 1
p1.AddNum(37); //access 2

Console.WriteLine("press any key");
Console.ReadLine();

私は本当に「アクセス 1」が失敗し、「アクセス 2」が値を設定できる唯一の方法であることを望んでいます。助けてくれてありがとう。

4

2 に答える 2

10

√ ReadOnlyCollection のサブクラスである ReadOnlyCollection を使用するか、まれに、読み取り専用コレクションを表すプロパティまたは戻り値に IEnumerable を使用します。

この記事からの引用。

次のようなものが必要です。

List<int> _nums = new List<int>();

public ReadOnlyCollection<int> Nums
{
    get
    {
        return _nums.AsReadOnly();
    }
}
于 2015-03-18T17:20:44.873 に答える
2

一般に、コレクション型は、コレクションが でラップされている場合でも、ReadOnlyCollection何が本質的に不明確であるため、不適切なプロパティになります。

IEnumerable<int> nums = myPerson.Nums;
myPerson.AddNum(23);
foreach(int i in nums) // Should the 23 be included!?
  ...

意味するはずです。オブジェクトは、Nums呼び出し時に存在していた番号のスナップショットから返されますか?それはライブ ビューですか?

GetNumsAsArrayよりクリーンなアプローチは、呼び出されるたびに新しい配列を返すようなメソッドを呼び出すことです。GetNumsAsList場合によっては、発信者が番号をどうしたいかによって、バリアントを用意しておくと便利な場合もあります。一部のメソッドは配列でのみ機能し、一部はリストでのみ機能します。したがって、上記のいずれかのみが提供されている場合、一部の呼び出し元はそれを呼び出して、返されたオブジェクトを必要な型に変換する必要があります。

パフォーマンスに敏感な呼び出し元がこのコードを頻繁に使用する必要がある場合は、より汎用的なメソッドを使用すると役立つ場合があります。

int CopyNumsIntoArray(int sourceIndex, int reqCount, ref int[] dest, 
                      int destIndex, CopyCountMode mode);

ここで、CopyCountMode は、コードが何をすべきかを示します。使用可能な項目の数は、sourceIndexより大きいか小さいかを示しreqCountます。メソッドは、利用可能なアイテムの数を返すか、呼び出し元の期待に違反した場合は例外をスローする必要があります。一部の呼び出し元は、最初に 10 項目の配列を作成して渡すことから始めるかもしれませんが、返される項目が 10 を超える場合は、メソッドがそれをより大きな配列に置き換える準備をしておく必要があります。他の人は、ちょうど 23 個のアイテムがあると予想し、他の数を処理する準備ができていないかもしれません。パラメーターを使用してモードを指定すると、1 つのメソッドでさまざまな種類の呼び出し元にサービスを提供できます。

多くのコレクション作成者は、上記のパターンに適合するメソッドを含めることを気にしませんが、そのようなメソッドは、コードがかなり少数のコレクション (たとえば、50,000 のコレクションのうちの 1,000 アイテム) で動作する場合に効率を大幅に向上させることができます。そのようなメソッドがない場合、そのような範囲で作業したいコードは、全体のコピーを要求するか (非常に無駄)、何千ものアイテムを個別に要求する必要があります (これも無駄です)。呼び出し元が宛先配列を指定できるようにすると、同じメソッドが多くのクエリを実行する場合、特に宛先配列が大きなオブジェクト ヒープに配置できるほど大きい場合に、効率が向上します。

于 2015-03-18T17:37:35.430 に答える