سؤال

عند القيام بمثابة أوفاق ، ماذا يحدث بالفعل وراء الكواليس؟ كان لدي فكرة أنه عند القيام بشيء ما يلي:

string myString = "abc";
object myObject = myString;
string myStringBack = (string)myObject;

كان من شأن الممثلين في السطر الأخير أن يخبر الغرض فقط للمترجم أننا آمنون أننا لا نفعل أي شيء خاطئ. لذلك ، كان لدي فكرة أنه في الواقع لن يتم تضمين رمز الصب في الكود نفسه. يبدو أنني كنت مخطئا:

.maxstack 1
.locals init (
    [0] string myString,
    [1] object myObject,
    [2] string myStringBack)
L_0000: nop 
L_0001: ldstr "abc"
L_0006: stloc.0 
L_0007: ldloc.0 
L_0008: stloc.1 
L_0009: ldloc.1 
L_000a: castclass string
L_000f: stloc.2 
L_0010: ret 

لماذا يحتاج CLR إلى شيء مثل castclass string?

هناك تطبيقان محتملان للتسرب:

  1. تحتاج castclass something. عندما تصل إلى سطر الكود الذي يقوم castclass, ، يحاول CLR جعل الممثلين. ولكن بعد ذلك ، ما الذي سيحدث لو كنت قد تميزت بخط سلسلة CastClass وحاولت تشغيل الرمز؟
  2. أنت لا تحتاج castclass. نظرًا لأن جميع الأنواع المرجعية لها بنية داخلية مماثلة ، إذا حاولت استخدام سلسلة على مثيل الشكل ، فسيتم إلقاء استثناء من الاستخدام الخاطئ (لأنه يكتشف نموذجًا ليس سلسلة أو أي من أنواعه الفرعية).

أيضا ، هل الإحصاء التالي من C# 4.0 باختصار صحيح؟

Upcasting and downcasting between compatible reference types performs reference
conversions: a new reference is created that points to the same object.

هل تخلق حقًا مرجعًا جديدًا؟ اعتقدت أنه سيكون نفس المرجع ، المخزنة فقط في نوع مختلف من المتغير.

شكرًا

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

المحلول

كان لدي فكرة أنه في الواقع لن يتم تضمين رمز الصب في الكود نفسه.

فكرة مثيرة للاهتمام. كيف تخيلت أن هذا يعمل؟

try
{
    object x = 123;
    object y = (string)x;
}
catch(InvalidCastException ex)
{ ... }

إذا كان فريق العمل لا ينتج أي رمز ثم أين يحدث الكود الذي يلقي الاستثناء?

تذكر الغرض الأساسي من طاقم من نوع أقل تحديدًا إلى نوع أكثر تحديدًا هو إجراء فحص نوع وقت التشغيل.

بمجرد أن يمر فحص النوع ، ثم بالتأكيد ، لا شيء آخر يجب أن يحدث حقًا. أجزاء المرجع قبل فحص النوع والبت بعد فحص النوع هي نفس البتات ؛ لقد كان لدينا فقط وقت التشغيل تحقق من أن الاستخدام الجديد للبتات القديمة له ما يبرره.

إذا حاولت استخدام سلسلة على مثيل الشكل ، فسوف يلقي استثناءً من الاستخدام الخاطئ (لأنه يكتشف نموذجًا ليس سلسلة أو أي من أنواعه الفرعية).

أين تكتشف ذلك؟ أعني ، في بالضبط أي تعليمات هل تم اكتشاف ذلك؟ في تعليمات castClass. هذا ما هي تعليمات castClass ل.

ما الذي سيحدث لو كنت أميل إلى خط سلسلة CastClass وحاولت تشغيل الرمز؟

كان من شأن التحقق من سلامة النوع رفض البرنامج الخاص بك. لو أجبرت CLR على تشغيله دون تمرير التحقق ، فسيكون له سلوك غير محدد. ربما تكون قد نجحت ، ربما فشلت ، ربما تكون قد قامت بتنسيق القرص الثابت.

هل تخلق حقًا مرجعًا جديدًا؟

تذكر ، على مستوى التنفيذ ، الإشارة مجرد عدد صحيح بحجم المؤشر. إنه رقم يمكن لمدير الذاكرة استخدامه لتتبع موضع البيانات المشار إليها. قد يكون مؤشرًا ، قد يكون مقبضًا ، ولا يهم ما هو عليه ؛ إنه شيء ينفذ الفكرة التجريدية للمرجع.

عندما يكون لديك متغير يحتوي على 12 وستستبدل محتوياته بـ 12 ، هل هذا "12 جديدًا" تم إنشاؤه للتو أم أنه "قديم" 12؟ لنفترض أنك تقوم بتقديم متغير ثانٍ وتضع 12 في ذلك أيضًا عن طريق النسخ من المتغير الأول. هل هذا "جديد" 12 أم "القديم" 12؟ كيف تستطيع أن تقول ذلك؟ إنه فرق لا فرق. عندما تقوم بإجراء مرجع "جديد" مماثل للإشارة "القديمة" ، فإن إنشاء شيء جديد؟ السؤال هو سؤال فلسفي ، وليس سؤالًا تقنيًا.

نصائح أخرى

أنت مربكة مرجع مع مثيل. جديد المرجعي تم إنشاؤه ، وليس مثيلًا جديدًا.

object foo = "bar";
string baz = (string)foo;

جديد المرجعي إلى السلسلة "foo" تم تعيينه إلى baz متغير (ولكن لا يزال هناك مثيل واحد فقط من السلسلة ، إنه مجرد أن كلا المتغيرين يشيران إلى المثيل الفردي). لو لم يكن هذا هو الحال ، سيكون لديك شيء أقرب إلى نوع "المقبض". إذا baz و foo كانت حرفيا نفس المرجع ، ثم هذا ..

foo = "bim";

سوف تجعل أيضا baz يساوي "bim" (وبالمثل ، فإن تعيين نوع غير سائق سيحدث baz لم تعد تشير إلى مرجع سلسلة صالحة).

يمكنك تنفيذ مصبوب على نوع مرجعي إما عندما يكونون في نفس الميراث الوريدي (يرث أحدهما من الآخر إما بشكل مباشر أو غير مباشر) أو عند وجود تحويل صريح بين الأنواع. لاحظ أن التحويلات الصريحة ، مثل جميع المشغلين الآخرين ، ليست متعددة الأشكال - أي التحويل يجب تعريفها على وجه التحديد على أحد الفصول المعنية, ، ليس في مرحلة أخرى في التسلسلات الوحيدة.

إن التحويل الصريح ، عند الحضور ، سيأخذ الأولوية حتى لو كانت الأنواع المعنية متوافقة بدونه. في حالة وجود تحويل صريح ، ليس لديك أي ضمان (في الواقع ، من غير المرجح للغاية) أن تكون نتيجة CAST/Conversion تشير إلى نفس مثيل الكائن الذي يجري التصوير.

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