سؤال

التعليمة البرمجية التالية يلقي خطأ وقت الترجمة مثل

لا يمكن تحويل النوع "سلسلة" إلى "int"

string name = Session["name1"].ToString();
int i = (int)name;

بينما يتم تجميع التعليمات البرمجية أدناه وتنفيذها بنجاح:

string name = Session["name1"].ToString();
int i = Convert.ToInt32(name);

أود أن أعلم:

  1. لماذا يُنشئ الكود الأول خطأً في وقت الترجمة؟

  2. ما الفرق بين مقتطفي الكود؟

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

المحلول

(int)foo هو مجرد يلقي ل Int32 (int في C#) النوع.هذا مدمج في CLR ويتطلب ذلك foo يكون متغيرًا رقميًا (على سبيل المثال float, long, ، وما إلى ذلك) وبهذا المعنى، فهي تشبه إلى حد كبير طاقم الممثلين في لغة C.

Convert.ToInt32 تم تصميمه ليكون وظيفة تحويل عامة.إنه يفعل أكثر بكثير من مجرد الصب.وهي أنه يمكن التحويل من أي النوع البدائي ل int (أبرزها تحليل أ string).يمكنك الاطلاع على القائمة الكاملة للأحمال الزائدة لهذه الطريقة هنا على MSDN.

و كما ستيفان ستيجر يذكر في تعليق:

لاحظ أيضًا أنه على المستوى العددي، (int) foo يقتطع foo (ifoo = Math.Floor(foo))، بينما Convert.ToInt32(foo) الاستخدامات نصف حتى التقريب (يقرب x.5 إلى أقرب عدد صحيح، مما يعني ifoo = Math.Round(foo)).وبالتالي فإن النتيجة لا تقتصر على التنفيذ فحسب، بل على المستوى العددي أيضًا لا نفس الشيء.

نصائح أخرى

(يتعلق هذا السطر بسؤال تم دمجه) يجب ألا تستخدمه أبدًا (int)someString - هذا لن ينجح أبدًا (ولن يسمح لك المترجم بذلك).

لكن، int int.Parse(string) و bool int.TryParse(string, out int) (وحمولاتها الزائدة المختلفة) هي لعبة عادلة.

انا شخصيا خاصة فقط استخدم Convert عندما أتعامل مع التفكير، فالخيار بالنسبة لي هو Parse و TryParse.الأول هو عندما أنا يتوقع أن تكون القيمة عددًا صحيحًا صالحًا، وتريد أن تطرح استثناءً بخلاف ذلك.والثاني عندما أريد ذلك يفحص إذا كان عددًا صحيحًا صالحًا - يمكنني بعد ذلك أن أقرر ما يجب فعله عندما يكون/لا يكون كذلك.

للاقتباس من هذا مقال إريك ليبرت:

الإلقاء يعني شيئين متناقضين:"تحقق لمعرفة ما إذا كان هذا الكائن من هذا النوع بالفعل، ثم قم برميه إذا لم يكن كذلك" و"هذا الكائن ليس من النوع المحدد؛ابحث لي عن قيمة معادلة تنتمي إلى النوع المحدد".

إذن ما كنت تحاول القيام به في 1.) هو التأكيد على أن نعم السلسلة هي Int.لكن هذا التأكيد يفشل لأن String ليس int.

السبب 2.) النجاح هو أن Convert.ToInt32() يوزع السلسلة ويعيد int.لا يزال من الممكن أن تفشل، على سبيل المثال:

Convert.ToInt32("Hello");

سيؤدي إلى استثناء وسيطة.

لتلخيص ذلك، يعد التحويل من String إلى Int أحد اهتمامات إطار العمل، وليس شيئًا ضمنيًا في نظام النوع .Net.

لا يمكن إرسال السلسلة إلى int من خلال الإرسال الصريح.يجب أن يتم تحويلها باستخدام int.Parse.

يلتف برنامج Convert.ToInt32 بشكل أساسي بهذه الطريقة:

public static int ToInt32(string value)
{
    if (value == null)
    {
        return 0;
    }
    return int.Parse(value, CultureInfo.CurrentCulture);
}

أنت تتحدث عن عملية صب C# مقابل أدوات تحويل .NET

  • مستوى لغة C# يصب يستخدم الأقواس - على سبيل المثال(int) - ودعم التحويل له محدود، ويعتمد على التوافق الضمني بين الأنواع، أو تعليمات محددة بوضوح من قبل المطور عبر مشغلي التحويل.
  • توجد العديد من طرق التحويل في .NET Framework، على سبيل المثال. System.Convert, ، لكى يسمح تحويل بين أنواع البيانات نفسها أو المتباينة.

(يصب) يعمل بناء الجملة على أنواع البيانات الرقمية، وكذلك على أنواع البيانات "المتوافقة"."متوافق" يعني أنواع البيانات التي توجد علاقة مثبتة لها من خلال الميراث (أي.الفئات الأساسية/المشتقة) أو من خلال التنفيذ (أيواجهات).

يمكن أن يعمل الإرسال أيضًا بين أنواع البيانات المختلفة التي تحتوي على مشغلي التحويل مُعرف.

ال System.Convert ومن ناحية أخرى، فإن الطبقة هي إحدى الآليات العديدة المتاحة لتحويل الأشياء بالمعنى العام؛يحتوي على منطق للتحويل بين أنواع البيانات المختلفة والمعروفة والتي يمكن تغييرها منطقيًا من نموذج إلى آخر.

يغطي التحويل بعضًا من نفس أسس الإرسال من خلال السماح بالتحويل بين أنواع البيانات المتشابهة.


تذكر أن لغة C# لها طريقتها الخاصة في القيام ببعض الأشياء.
و.NET Framework الأساسي له طريقته الخاصة في القيام بالأشياء، بصرف النظر عن أي لغة برمجة.
(في بعض الأحيان يتداخلون في نواياهم).

فكر في الإرسال كميزة على مستوى لغة C# محدودة بطبيعتها، والتحويل عبر فئة System.Convert كواحدة من العديد من الآليات المتاحة في إطار عمل .NET لتحويل القيم بين أنواع مختلفة.

لا يوجد تحويل افتراضي من السلسلة إلى int في .NET.يمكنك استخدام int.Parse() أو int.TryParse() للقيام بذلك.أو، كما فعلت، يمكنك استخدام Convert.ToInt32().

ومع ذلك، في المثال الخاص بك، لماذا تستخدم ToString() ثم تقوم بتحويلها مرة أخرى إلى int على الإطلاق؟يمكنك ببساطة تخزين int في الجلسة واستعادته كما يلي:

int i = Session["name1"];

مجرد إضافة موجزة:في ظروف مختلفة (على سبيل المثال.إذا كنت تقوم بتحويل مزدوج، &c إلى Int32) فقد ترغب أيضًا في القلق بشأن التقريب عند الاختيار بين هذين.سيستخدم Convert.Int32 تقريب المصرفي (MSDN);(int) سيتم اقتطاعه إلى عدد صحيح.

1) لغة C# هي لغة آمنة للكتابة ولا تسمح لك بتعيين سلسلة لرقم

2) الحالة الثانية بتوزيع السلسلة إلى متغير جديد.في حالتك، إذا كانت الجلسة هي جلسة ASP.NET، فلن تضطر إلى تخزين السلسلة هناك وتحويلها مرة أخرى عند استردادها

int iVal = 5;
Session[Name1] = 5;
int iVal1 = (int)Session[Name1];

تحويل.ToInt32

    return int.Parse(value, CultureInfo.CurrentCulture);

لكن (int) هو نوع cast، لذلك لن يعمل (int)"2" نظرًا لأنه لا يمكنك إرسال السلسلة إلى int.ولكن يمكنك تحليلها كما تفعل Convert.ToInt32

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

هذا قديم، ولكن هناك اختلاف آخر وهو أن (int) لا يقوم بتقريب الأرقام في حالة وجود ej مزدوج:5.7 سيكون الإخراج باستخدام (int) 5 وإذا كنت تستخدم Convert.ToInt() فسيتم تقريب الرقم إلى 6.

لقد تمت مناقشة هذا بالفعل ولكني أرغب في مشاركة dotnetfiddle.

إذا كنت تتعامل مع العمليات الحسابية وتستخدم التعويم والعشري والمزدوج وما إلى ذلك، فمن الأفضل استخدام Convert.ToInt32().

using System;

public class Program
{
  public static void Main()
  {
    double cost = 49.501;
    Console.WriteLine(Convert.ToInt32(cost));
    Console.WriteLine((int)cost);
  }
}

انتاج |

50
49

https://dotnetfiddle.net/m3ddDQ

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