يصب:(نوع جديد) مقابل.كائن كنوع جديد [مكرر]

StackOverflow https://stackoverflow.com/questions/2483

  •  08-06-2019
  •  | 
  •  

سؤال

التكرار المحتمل:
الإرسال مقابل استخدام الكلمة الأساسية "as" في CLR

ما هو في الواقع الفرق بين هذين الممثلين؟

SomeClass sc = (SomeClass)SomeObject;
SomeClass sc2 = SomeObject as SomeClass;

عادةً، يجب أن يكون كلاهما مصبوبًا بشكل صريح للنوع المحدد؟

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

المحلول

سوف يطرح الأول استثناءً إذا تعذر تحويل النوع المصدر إلى النوع الهدف.سيؤدي الأخير إلى كون sc2 مرجعًا فارغًا، ولكن ليس استثناءً.

[يحرر]

إجابتي الأصلية هي بالتأكيد الفرق الأكثر وضوحًا، ولكن كما قال إيريك ليبرت يشير الى, ، انها ليست الوحيدة.تشمل الاختلافات الأخرى ما يلي:

  • لا يمكنك استخدام عامل التشغيل "as" للإرسال إلى نوع لا يقبل "null" كقيمة
  • لا يمكنك استخدام "كما" ل يتحول الأشياء، مثل الأرقام لتمثيل مختلف (تعويم إلى كثافة العمليات، على سبيل المثال).

وأخيرًا، استخدام "as" مقابل "as".مشغل فريق التمثيل، فأنت تقول أيضًا "لست متأكدًا من نجاح هذا الأمر."

نصائح أخرى

لاحظ أيضًا أنه لا يمكنك استخدام الكلمة الأساسية إلا مع نوع مرجعي أو نوع لاغٍ

أي:

double d = 5.34;
int i = d as int;

لن تجميع

double d = 5.34;
int i = (int)d;

سوف تجميع.

يعد التلبيس باستخدام "as" بالطبع أسرع بكثير عندما يفشل الإرسال، لأنه يتجنب تكلفة طرح استثناء.

لكن الأمر ليس أسرع عندما ينجح طاقم الممثلين.الرسم البياني في http://www.codeproject.com/KB/cs/csharpcasts.aspx مضلل لأنه لا يشرح ما يقيسه.

خلاصة القول هي:

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

  • إذا كنت لا تعرف ما إذا كان سينجح، فاستخدم عامل التشغيل "as" واختبر النتيجة على أنها خالية.

الفرق بين الطريقتين هو أن الأول ((SomeClass)obj) قد يتسبب في حدوث محول النوع ليتم استدعاؤها.

إليك طريقة جيدة لتذكر العملية التي يتبعها كل منهم والتي أستخدمها عند محاولة تحديد أيهما أفضل لظروفي.

DateTime i = (DateTime)value;
// is like doing
DateTime i = value is DateTime ? value as DateTime : throw new Exception(...);

ويجب أن يكون من السهل تخمين ما يفعله التالي

DateTime i = value as DateTime;

في الحالة الأولى، إذا تعذر إرسال القيمة، فسيتم طرح استثناء في الحالة الثانية، إذا تعذر إرسال القيمة، فسيتم تعيين i على null.

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

حسنًا يساعدك عامل التشغيل "as" على دفن مشكلتك بطريقة أقل لأنه عندما يتم توفير مثيل غير متوافق فإنه سيعود فارغًا، ربما ستمرر ذلك إلى طريقة ستمرره إلى طريقة أخرى وما إلى ذلك، وفي النهاية ستحصل على NullReferenceException مما سيجعل تصحيح الأخطاء أكثر صعوبة.

لا تسيء استخدامه.يعتبر عامل الصب المباشر أفضل في 99% من الحالات.

للتوسع في تعليق ريتميس, ، لا يمكنك استخدام مثل الكلمة الأساسية للبنيات (أنواع القيمة)، لأنها لا تحتوي على قيمة فارغة.

ينطبق كل هذا على أنواع المراجع، ولا يمكن لأنواع القيم استخدام التابع as الكلمة الأساسية لأنها لا يمكن أن تكون فارغة.

//if I know that SomeObject is an instance of SomeClass
SomeClass sc = (SomeClass) someObject;


//if SomeObject *might* be SomeClass
SomeClass sc2 = someObject as SomeClass;

يكون بناء جملة الإرسال أسرع، ولكن عندما يكون ناجحًا فقط، يكون الفشل أبطأ بكثير.

أفضل الممارسات هي الاستخدام as عندما لا تعرف النوع:

//we need to know what someObject is
SomeClass sc;
SomeOtherClass soc;

//use as to find the right type
if( ( sc = someObject as SomeClass ) != null ) 
{
    //do something with sc
}
else if ( ( soc = someObject as SomeOtherClass ) != null ) 
{
    //do something with soc
}

ولكن إذا كنت متأكدا تماما من ذلك someObject هو مثال على SomeClass ثم استخدم الزهر.

في .Net 2 أو أعلى، تعني أنك نادرًا ما تحتاج إلى مثيل غير مكتوب لفئة مرجعية، لذلك يتم استخدام الأخير بشكل أقل.

يلقي طاقم التمثيل بين قوسين استثناءً في حالة فشل محاولة الإرسال.تُرجع عملية الإرسال "as" فارغة في حالة فشل محاولة الإرسال.

سوف يرميون استثناءات مختلفة.
() :NullReferenceException
مثل :InvalidCastException
والتي يمكن أن تساعد في تصحيح الأخطاء.

تحاول الكلمة الأساسية "as" إرسال الكائن وإذا فشل الإرسال، فسيتم إرجاع القيمة null بصمت.سيقوم عامل الإرسال () بطرح استثناء على الفور في حالة فشل الإرسال.

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

للحصول على أمثلة التعليمات البرمجية ومزيد من التوضيح: http://blog.nerdbank.net/2008/06/when-not-to-use-c-keyword.html

إنه مثل الفرق بين Parse وTryParse.يمكنك استخدام TryParse عندما تتوقع احتمال فشله، ولكن عندما يكون لديك ضمان قوي بأنه لن يفشل، يمكنك استخدام Parse.

لأولئك منكم الذين لديهم خبرة في VB.NET، (النوع) هو نفس DirectCast و"كنوع" هو نفس TryCast.

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