1

クラスがあります。

public class abc
{
    public int i = 0;
    public string a = "";
}

=======================================

今、タイプabcクラスのリストにいくつかのレコードを挿入しています

List<abc> c = new System.Collections.Generic.List<abc>();
abc a = new abc();
a.a = "1";
a.i = 1;
c.Add(a);

a = new abc();
a.a = "1";
a.i = 2;
c.Add(a);

===========================================

リスト変数を作成し、フィルター処理されたレコードをいくつか追加します。

List<abc> temp = new System.Collections.Generic.List<abc>();

temp.AddRange(c.Where(i => i.i == 1));

===============================================

クエリ = 以下のコード行を実行すると、c 変数も変更されます。

私は両方が同じメモリ位置を指していることを知っています。このコードを修正する方法はありますか?

foreach (abc d in temp)
{
    d.i = 10;
}
4

3 に答える 3

4

「なぜリストを更新すると別のリストが更新されるのか」ではありません。

「リスト内のインスタンスを更新すると、別のリスト内の同じインスタンスが更新されるのはなぜですか?」

classこのクラスの同じインスタンスを使用しているためです。

List<abc> list1 = new List<abc>();
list1.Add(new abc());  // new abc() creates an instance of the abc() class. Let's call this instance myInstance

List<abc> list2 = new List<abc>();
list2.Add(list1[0]);  // Here you add the same instance (ie. myInstance) to the list2

list1[0].a = 5;  // You modify the instance myinstance

Console.WriteLine(list2[0].a);   // Returns "5"  (because it is always the same instance myIsntance)

この動作を回避するには、2 つの解決策があります。

Clone メソッドを作成して、同じ値を持つ abc のインスタンスを複製します。

public class abc
{
    public int i = 0;
    public string a = "";

    public abc Clone(abc instanceToClone)
    {
        abc result = new abc();
        result.i = instanceToClone.i;
        result.a = instanceToClone.a;
    }
}

または、クラスを構造体に置き換えます (その後、値の型はありますが、フィールド初期化子を持つことはできません)。

public struct abc
{
    public int i;  // Initialized by default to 0
    public string a;  // Initialized by default to null
}

この優れた記事を読んで、C# の「基本」概念を理解することをお勧めします。(簡単ではありませんが、とても重要です)

于 2013-01-29T12:59:50.663 に答える
3

必要なときにいつでもオブジェクトのクローンを作成します。たとえば、 ifiaがプロパティだった場合は、完全にそうあるべきです! -- 書くこともできた

temp.AddRange(c.Where(i => i.i == 1).Select(o => new abc { a = o.a, i = o.i}));
于 2013-01-29T13:00:31.803 に答える
0

オブジェクト インスタンスに加えられた更新は、そのインスタンスのすべての所有者に表示されます。コレクション オブジェクトがいくつ配置されていても、どのタイプのコレクションに含まれていても、変更はどこでも表示されます。これは、コレクションがメモリ内の同じ場所のみを指しているためです。どこで変更しても、どこでも表示されます。

このような動作を回避する必要がある場合は、次の 2 つのオプションがあります。

  • 1 つのコレクション内でオブジェクトを複製する
  • structの代わりに使用class


public struct abc
{
    int i;
    string a;
}

abc a, b;
...
a.i = 1;
b = a;
/* new memory location is allocated for `b`, and values are copied from `a`.
therefore, updates made to `a` will not affect `b`*/
b.i = 2;
if (a.i == b.i)
    throw new Exception("i values are same");
于 2013-01-29T13:08:58.103 に答える