سؤال

لدي متغير في السؤال حسب المرجع.أعرف كل شيء عن الاتصال بالمرجع أو المعلمات الخاصة بنا وكيف يؤثر ذلك على المتغيرات وقيمها.لقد واجهت هذه المشكلة مع DataTable وأريد أن أعرف سبب اختلاف 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);

        }

تعرض وحدة التحكم:stringcol stringcol123 اختبار اختبار

بقول mVar4 = mVar3، فإنه يجعل mVar4 مرجعًا لـ mVar3.

الحل لهذه المشكلة هو القول

DataTable mVar4 = mVar3.Copy(); 

لذلك سؤالي هو:ما الذي يجعل أداء جدول البيانات مختلفًا عن حقل عدد صحيح بسيط.لماذا يقوم بإنشاء مرجع عندما أستخدم mVar4 = mVar3 بدلاً من نسخة مختلفة من DataTable؟

هل كانت مفيدة؟

المحلول

وأنت تعمل ضد الفرق بين نوع مرجع ونوع قيمة.

وإليك MSDN المقالة على الخلافات .

ومن شأن الإجابة أكثر وصفية يكون أن كل من هي في الواقع تقوم بنفس العملية، والفرق هو أن في المثال الأول (اثنين من الأعداد الصحيحة) تعيين 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;
}

نصائح أخرى

الاستدعاء mVar2 = mVar1;نسخ القيمة المخزنة في موقع mVar1.في هذا السيناريو، يعني ذلك أنه تم نسخ 1 في الموقع mVar2.في الحالة الثانية، يتم نسخ القيمة المخزنة في 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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top