2

byrefの質問にバリアントがあります。refまたはパラメーターを使用して呼び出すことと、それが変数とその値にどのように影響するかについては、すべて知っています。DataTableでこの問題が発生しましたが、データテーブルが単純な整数変数と異なる理由を知りたいです。

私は問題を解決する方法について物理的な答えを持っていますが、なぜそれがそのように機能するのか知りたいです。

単純な変数を使用すると、私が期待したことを実行します

        int mVar1 = 1;
        int mVar2 =1;

        mVar2 = mVar1;

        mVar2 = 5;

        Console.WriteLine(mVar1.ToString());
        Console.WriteLine(mVar2.ToString());

コンソールに1.5が表示されます。

ただし、DataTableで同じことを行うと、新しい値ではなく、最初のデータテーブルへの参照が作成されます。

        DataTable mVar3 = new DataTable();
        DataTable mVar4 = new DataTable();


         // Create DataColumn objects of data types.
        DataColumn colString = new DataColumn("StringCol");
        colString.DataType = System.Type.GetType("System.String");
        mVar3.Columns.Add(colString);

        // Create DataColumn objects of data types.
        DataColumn colString2 = new DataColumn("StringCol123");
        colString2.DataType = System.Type.GetType("System.String");
        mVar4.Columns.Add(colString2);

        foreach (DataColumn tCol in mVar3.Columns)
        {
            Console.WriteLine(tCol.ColumnName);

        }
        foreach (DataColumn tCol in mVar4.Columns)
        {
            Console.WriteLine(tCol.ColumnName);

        }

                mVar4 = mVar3;

        //change mVar4 somehow and see if mVar3 changes


        foreach (DataColumn tCol in mVar4.Columns)
        {
            tCol.ColumnName = "Test";

        }

        foreach (DataColumn tCol in mVar3.Columns)
        {
            Console.WriteLine(tCol.ColumnName);

        }

        foreach (DataColumn tCol in mVar4.Columns)
        {
            Console.WriteLine(tCol.ColumnName);

        }

コンソールに次のように表示されます。StringColStringCol123テストテスト

mVar4 = mVar3と言うと、mVar4がmVar3への参照になります。

この問題の解決策は言うことです

DataTable mVar4 = mVar3.Copy(); 

だから私の質問は:データテーブルが単純な整数フィールドとは異なる動作をする原因は何ですか?DataTableの別のコピーの代わりにmVar4=mVar3を使用すると、なぜ参照が作成されるのですか?

4

2 に答える 2

2

参照型と値型の違いに直面しています。

これは違いに関するmsdnの記事です。

より説明的な答えは、両方が実際には同じ操作を実行しているということです。違いは、最初の例 (2 つの整数) では、mVar2 = mVar1 の割り当てが mVar1 の値を mVar2 に割り当てていることです。これは 1 です。 DataTable の場合、実際に割り当てられるのは DataTable ではなくメモリ ロケーションです。

たとえば、作成した DataTable がメモリ位置 20 にあるとします。これは、参照 mVar1 がその場所 (20) への参照を保持することを意味します。割り当て mVar2 = mVar1 を実行すると、mVar2 に mVar1 と同じ値を保持するように指示されるため、mVar2 はメモリ位置 20 も参照します。その結果、両方の変数が同じ DataTable を参照します。

あなたが説明している動作を実現するには、あなたが述べたように、実際にコピー能力が必要です。まったく新しいオブジェクトを割り当て、前のオブジェクトの状態を新しいオブジェクトにコピーする必要があります。

DataTable クラスの場合、拡張メソッド内で次のように拡張できます。

public static DataTable Copy(this DatTable original)
{
   var result = new DataTable();
   //assume Property1 was a property of a DataTable
   result.Property1 = original.Property1; 
   //continue copying state from original to result
   return result;
}
于 2009-06-23T15:49:09.473 に答える
0

呼び出し mVar2 = mVar1; mVar1 の場所に格納されている値をコピーします。このシナリオでは、1 が場所 mVar2 にコピーされることを意味します。2 番目の状況では、mVar3 に保存されている値が mVar4 の場所に再度コピーされます。ただし、この場合、DataTable は参照型であるため、コピーされる値は実際の DataTable オブジェクトへの参照です。

これをさらに表示するには、投稿したコードの最後に次を追加します。

        mVar4 = new DataTable();
        // Create DataColumn objects of data types.
        DataColumn colString3 = new DataColumn("StringCol1234");
        colString2.DataType = System.Type.GetType("System.String");
        mVar4.Columns.Add(colString3);

        foreach (DataColumn tCol in mVar3.Columns)
        {
            Console.WriteLine(tCol.ColumnName); // still outputs test

        }

        foreach (DataColumn tCol in mVar4.Columns)
        {
            Console.WriteLine(tCol.ColumnName); // now outputs StringCol1234

        }

ここで、mVar4 を DataTable の新しいインスタンスに再度設定すると、加えられた変更は mVar3 に反映されません。これは、呼び出し mVar4 = new DataTable(); が原因です。mVar4 の場所の参照を変更しますが、mVar4 が参照するオブジェクトは変更しません。

于 2009-06-23T15:46:53.283 に答える