لا يمكن تحويل نوع "السلسلة" إلى "int؟" عبر تحويل مرجعي، تحويل الملاكمة، تحويل Unboxing، تحويل التفاف أو تحويل نوع NULL

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

  •  23-08-2019
  •  | 
  •  

سؤال

C # يقبل ما يلي:

object o = "hello";
int? i = o as int?;

if (i == null) {
    // o was not a boxed int
}
else {
    // Can use i.Value to recover the original boxed value
}

لكن لا

String o = "hello";
int? i = o as int?;

if (i == null) {
    // o was not a boxed int
}
else {
    // Can use i.Value to recover the original boxed value
}

أنا فقط أتساءل عن سلوك الكلمة الرئيسية as في ج #.

كما هو الحال في Java هذا سيفشل:

Object test1 = "hello";
Integer test2 = (Integer) test1;
String test3 = "hello";
Integer test4 = (Integer) test3; //compilation error
هل كانت مفيدة؟

المحلول

يعلم المحول البرمجي أن سلسلة لا يمكن أن تكون أبدا int? لذلك يخبرك بذلك. هذا لا يعني ذلك int? ليست مفيدة. حالة استخدام الخاص بك هي بعيدة عن المعتاد. المعتاد هو "أريد أن تمثل عدد صحيح وإمكانية أن تكون القيمة مفقودة / غير معروفة". من أجل هذا، int? يعمل بشكل جيد للغاية.

لماذا سوف توقع الكود الأصلي للعمل؟ لماذا سيكون مفيدا؟

لاحظ أنك يمكن استعمال as مع أنواع nullable، لبركة Unboxing:

object o = "hello";
int? i = o as int?;

if (i == null)
{
    // o was not a boxed int
}
else
{
    // Can use i.Value to recover the original boxed value
}

تحرير: بعد أن رأيت تعليقك، لا تستخدم as لتحليل الأشياء. ربما تريد استخدام int.TryParse:

string text = "123":
int value;
if (int.TryParse(text, out value))
{
    Console.WriteLine("Parsed successfully: {0}", value);
}
else
{
    Console.WriteLine("Unable to parse text as an integer");
}

إذا كنت متأكدا من أن السلسلة من المقصود أن تكون عددا صحيحا (أي خطأ خلاف ذلك)، فيمكنك فقط استخدام int.Parse:

int value = int.Parse(text);

من شأنها أن رمي استثناء إذا فشل التحليل.

لاحظ أيضا أن كل من هذه الأساليب يسمح لك بتحديد موفر تنسيق (عادة معلومات ثقافية) التي تتيح لك التعبير عن كيفية التعبير عن الأرقام في هذا التنسيق (مثل الفواصل الآلاف).

تحرير: في الإجابة على سؤالك الجديد، يمنع المحول البرمجي هذا لأنه يعرف سلسلة لا يمكن ربما كن مكتدا محاصر - لن ينجح التحويل أبدا. عندما يعرف فقط أن القيمة الأصلية هي كائن، فإنه ربما ينجح.

على سبيل المثال، لنفترض أنني قلت لك، "إليك شكل: هل هو مربع؟" هذا سؤال معقول. من المعقول أن نسأل ذلك: لا يمكنك معرفة دون النظر إلى الشكل.

ومع ذلك، قلت: "هنا مثلث: هل هو مربع؟" عندها ستكون من الحقوق بشكل معقول أن تضحك في وجهي، حيث لا يمكن أن يكون مثلث مربعة - لا معنى السؤال.

نصائح أخرى

كثافة يعني نوع عدد صحيح Nullable، وليس Int يمكن أن يحتوي على أي نوع آخر من المتغير.

إذا كنت تريد نوع متغير يمكن أن يحتوي على INT أو سلسلة، فمن الضروري استخدام كائن، أو سلسلة أفترض، ثم أعيش حياة مليئة بالكوع الصب. لا أعرف لماذا تريد أن تفعل ذلك، رغم ذلك.

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

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

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

بسبب الكلمة الرئيسية مختوم, ، يعرف المترجم أيضا أنك لا تستطيع ورث من system.string. لإضافة وظيفة أو تنفيذ بعض الواجهات الإضافية.

الرمز أدناه هو مثال وسيقوم المحول البرمجي بإلقاء الخطأ التالي على الترجمة

لا يمكن تحويل نوع "SealedClass" إلى "IcastTointerFace" عبر تحويل مرجعي، تحويل الملاكمة، تحويل Unboxing، تحويل التفاف، أو تحويل نوع NULL

public class UnsealedClass {
  // some code
}

public sealed class SealedClass {
  // some code
}

public interface ICastToInterface {
  // some code
}

public class Test {

  public Test() {
    UnsealedClass unsealedClass = new UnsealedClass();

    SealedClass sealedClass = new SealedClass();

    ICastToInterface unsealedCast = unsealedClass as ICastToInterface;  // This works fine

    ICastToInterface sealedCast = sealedClass as ICastToInterface; // This won´t compile, cause SealedClass is sealed
  }
}

ولكن يمكنك التحقق من قيمة NULL وتعيينها إلى NULL.

int? blah;
if (blah == null)
{}

كثافة يعد عددا صحيحا غير قابل للانهيار، لا علاقة له بالبقاء والكلمة الأساسية. "السلسلة" هي كائن نوع السلسلة، وهو غير قابل للتحويل إلى int (nullable أو غير غير قابلة للانفصال).

الكلمة الأساسية هي نفسها تقريبا مثل الصب باستخدام الأقواس باستثناء أنها لن ترجع خطأ، وسوف يقوم بتعيين الكائن إلى NULL:

int i = 1;

object o = i; //boxing

int j = (int)o; //unboxing

يعمل هذا المثال الأول ككائن معين إلى O هو int.

النظر الآن:

string i = "MyString";

object o = MyString;

 int j = (int)o //unboxing raises exception

 int j = o as int; //raises compilation Error as int is not nullable
 int? j = o as int?; /// o == null

آمل أن يساعد ذلك في تفسير الفرق بين المفهومين.

ريتشارد

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