سؤال

في جيسي الحرية تعلم C# الكتاب يقول "كائنات من نوع واحد يمكن تحويلها إلى كائنات من نوع آخر.وهذا ما يسمى الصب."

إذا كنت التحقيق IL المتولدة من التعليمات البرمجية أدناه يمكنك أن ترى بوضوح أن مسبوك مهمة لا تفعل نفس الشيء مثل تحويل المهمة.في السابق, يمكنك أن ترى الملاكمة/علبته تحدث ؛ في الأخير يمكنك أن ترى دعوة إلى تحويل الأسلوب.

أنا أعرف في النهاية قد يكون مجرد سخيفة الدلالي الفرق لكن هو صب مجرد كلمة أخرى لتحويل.أنا لا أقصد أن يكون المتعرج ، ولكن أنا غير مهتم في أي الشعور الغريزي على هذا-آراء لا تعول هنا!يمكن لأي شخص أن يشير إلى نهائي المرجعية التي تؤكد أو تنفي إذا صب وتحويل هي نفس الشيء ؟

    object x;
    int y;

    x = 4;

    y = ( int )x;

    y = Convert.ToInt32( x );

شكرا لك

rp

ملاحظة وأضاف بعد مات التعليق عن صريح/الضمني:

لا أعتقد الضمني/الصريح هو الفرق.في مدونة نشرت التغيير هو صريح في كلتا الحالتين.ضمني التحويل هو ما يحدث عند تعيين قصيرة إلى int.

ملاحظة Sklivvz:

أردت التأكيد على أن ظني رخاوة جيسي الحرية (وإلا عادة واضح واضح) اللغة الصحيحة.ظننت أن جيسي الحرية كان يجري قليلا فضفاضة مع لغته.أنا أفهم أن الصب يتم توجيهها في التسلسل الهرمي كائن-أي لا يمكن أن يلقي من عدد صحيح في السلسلة ولكن هل يمكن أن يلقي من استثناء مخصصة المستمدة من النظام.استثناء System.الاستثناء.

انها مثيرة للاهتمام على الرغم من أن عندما حاول أن يلقي من الباحث إلى سلسلة المترجم يقول لك أنه لا يمكن "تحويل" قيمة.ربما جيسي هو الأصح مما كنت اعتقد!

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

المحلول

الجواب البسيط هو:ذلك يعتمد.

القيمة أنواع الصب سيشمل حقا تحويله إلى نوع مختلف.على سبيل المثال:

float f = 1.5f;
int i = (int) f; // Conversion

عندما صب التعبير unboxes النتيجة (على افتراض أنه يعمل) ، عادة مجرد نسخ ما كان في الصندوق ، مع نفس النوع.لكن هناك استثناءات - يمكنك خدمة unbox من محاصر الباحث إلى enum (مع الكامنة نوع int) والعكس بالعكس ؛ كذلك يمكنك خدمة unbox من محاصر الباحث إلى Nullable<int>.

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

object o = "hello";
string x = (string) o; // No data is "converted"; x and o refer to the same object

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

كل هذه اعتباره التحويلات من حيث المواصفات لكن لم يحسب تحويل وجوه في وجوه من نوع مختلف.وأظن أن هذا هو حال من جيسي الحرية كونها فضفاضة مع المصطلحات - لقد لاحظت هذا في البرمجة C# 3.0 التي كنت أقرأ.

لا تغطي كل شيء ؟

نصائح أخرى

بالتأكيد لا!

تحويل يحاول Int32 عبر "بأي وسيلة ممكنة".يلقي لا شيء من هذا القبيل.مع يلقي كنت تقول مترجم لعلاج وجوه الباحث ، من دون تحويل.

يجب عليك دائما استخدام الزهر عندما تعرف (حسب التصميم) أن الكائن Int32 أو فئة أخرى أن صب المشغل Int32 (مثل تطفو على سبيل المثال).

تحويل ينبغي أن تستخدم مع سلسلة أو مع الطبقات الأخرى.

جرب هذا

static void Main(string[] args)
{
    long l = long.MaxValue;

    Console.WriteLine(l);

    byte b = (byte) l;

    Console.WriteLine(b);

    b = Convert.ToByte(l);

    Console.WriteLine(b);

}

النتيجة:

9223372036854775807

255

حدث استثناء غير معالج:

النظام.OverflowException:القيمة أكبر من وحدات البايت.MaxValue أو أقل من البايت.MinValue في النظام.تحويل.ToByte (Int64 قيمة) [0x00000] في الاختبار.الرئيسية (نظام.String[] args) [0x00019] في /home/ماركو/تطوير/اختبار/الاستثناءات.cs:15

أفضل تفسير التي رأيتها يمكن أن يرى أدناه ، تليها رابط المصدر:

"...الحقيقة هي قليلا أكثر تعقيدا من ذلك..صافي يوفر ثلاث طرق الحصول على من النقطة ألف إلى النقطة B ، كما كان.

أولا هناك الضمني المدلى بها.هذا هو يلقي هذا لا تتطلب منك أن تفعل أي شيء أكثر من مهمة:

int i = 5;
double d = i;

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

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

علما بأن الأساسية التمثيل هل تغيير في هذا التحويل:مزدوجة تتمثل بشكل مختلف تماما من الباحث.

أما النوع الثاني من التحويل هو صريح المدلى بها.صريح يلقي المطلوب كلما كان هناك احتمال فقدان المعلومات أو هناك احتمال أن يلقي قد لا تكون صحيحة وبالتالي رمي وهو InvalidCastException:

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

هنا من الواضح أنك سوف تفقد المعلومات:سوف تكون 1 بعد الزهر ، لذلك 0.5 يضيع.هذا هو المعروف أيضا باسم "تضييق" التحويل البرمجي يتطلب أن تشمل صريح الزهر (int) للإشارة إلى أن نعم ، أنت تعرف أنه قد يتم فقدان المعلومات ، ولكن كنت لا تهتم.

وبالمثل ، مع الإشارة أنواع مترجم يتطلب قوالب صريح في الحالات التي يلقي قد لا تكون صالحة في وقت التشغيل, إشارة أن نعم, كنت أعرف أن هناك خطر ، ولكن هل تعرف ما تفعلونه.

النوع الثالث من التحويل هو الذي ينطوي على مثل هذا التغيير الجذري في التمثيل أن المصممين لم توفر حتى صريحة المدلى بها:أنها تجعلك استدعاء أسلوب من أجل القيام التحويل:

string s = "15";
int i = Convert.ToInt32(s);

علما أنه لا يوجد شيء على الاطلاق يتطلب استدعاء الأسلوب هنا.الضمنية والصريحة يلقي هي طريقة المكالمات أيضا (هكذا تصنع الخاصة بك).المصممين يمكن بسهولة تامة خلقت صريح يلقي مشغل تحويل سلسلة إلى int.شرط أن يمكنك استدعاء الأسلوب هو الأسلوبية الاختيار بدلا من الأساسي شرط اللغة.

الأسلوبية المنطق يذهب شيء من هذا القبيل:String الى int هو معقدة التحويل مع الكثير من الفرص الأمور خاطئ:

string s = "The quick brown fox";
int i = Convert.ToInt32(s);

مثل استدعاء الأسلوب يعطيك وثائق لقراءة واسع إشارة إلى أن هذا هو شيء أكثر من مجرد سريعة المدلى بها.

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

  • بروس الخشب, 16 تشرين الثاني / نوفمبر 2005

http://bytes.com/forum/post1068532-4.html

صب ينطوي على إشارات

List<int> myList = new List<int>();
//up-cast
IEnumerable<int> myEnumerable = (IEnumerable<int>) myList;
//down-cast
List<int> myOtherList = (List<int>) myEnumerable;

لاحظ أن عمليات ضد قائمتي ، مثل إضافة عنصر ، تنعكس في myEnumerable و myOtherList.هذا هو لأنها كلها المراجع (من أنواع مختلفة) إلى نفس الدرجة.

حتى الصب آمنة.أسفل الصب يمكن أن تولد أخطاء وقت التشغيل إذا كان المبرمج قد أخطأ في الكتابة.آمنة أسفل الصب هو خارج نطاق هذا الجواب.

تحويل ينطوي الحالات

List<int> myList = new List<int>();
int[] myArray = myList.ToArray();

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

decimal w = 1.1m;
int x = (int)w;

هناك عمليات باستخدام يلقي الجملة في C# التي هي فعلا التحويلات.

دلالات جانبا ، اختبار سريع يوضح هم لا تعادل !
يفعلون المهمة بشكل مختلف (أو ربما يقومون بمهام مختلفة).

x=-2.5 (int)x=-2 Convert.ToInt32(x)=-2
x=-1.5 (int)x=-1 Convert.ToInt32(x)=-2
x=-0.5 (int)x= 0 Convert.ToInt32(x)= 0
x= 0.5 (int)x= 0 Convert.ToInt32(x)= 0
x= 1.5 (int)x= 1 Convert.ToInt32(x)= 2
x= 2.5 (int)x= 2 Convert.ToInt32(x)= 2

لاحظ x=-1.5 و x=1.5 الحالات.

الزهر هو قول مترجم/interperter أن الكائن هو في الواقع من هذا النوع (أو basetype/واجهة من هذا النوع).انها سريعة جدا أن تفعل الشيء مقارنة تحويل حيث انها لم تعد مترجم/interperter يقوم بهذه المهمة ولكن وظيفة actualling تحليل سلسلة والقيام الرياضيات تحويل إلى رقم.

صب دائما يعني تغيير نوع بيانات كائن.هذا يمكن القيام به على سبيل المثال عن طريق تحويل عدد عشري قيمة إلى قيمة عدد صحيح أو إعادة بت.فمن usally لغة تدعمها (قراءة:مترجم-معتمدة) العملية.

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

في اللغة / الإطار-الملحد طريقة الكلام, تحويل من نوع واحد أو فئة إلى أخرى كما هو معروف صب.هذا صحيح بالنسبة .صافي كما أول أربعة خطوط العرض:

object x;
int y;

x = 4;

y = ( int )x;

ج ج-مثل اللغات (مثل C#) استخدام (newtype)somevar بناء الجملة من أجل الصب.في VB.NET على سبيل المثال هناك صريحة المدمج في وظائف هذا.السطر الأخير سيكون كما هو مكتوب:

y = CInt(x)

أو أكثر تعقيدا أنواع:

y = CType(x, newtype)

حيث 'ج' من الواضح قصيرة 'الزهر'.

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

كما مات يقول الفرق في السلوك هو أن Convert() هو أكثر وضوحا.بدلا من مجرد إخبار المترجم لعلاج y كما عدد صحيح أي ما يعادل x, أنت على وجه التحديد تقول أن يغير x في مثل هذه الطريقة التي هي مناسبة صحيح الصف ، ثم تعيين نتيجة y.

في حالة معينة ، صب ما يسمى 'علبته' ، في حين Convert() في الواقع الحصول على قيمة عدد صحيح.سوف تظهر النتيجة نفسها ، ولكن هناك اختلافات أفضل وأوضح كيث.

وفقا الجدول 1-7 بعنوان "أساليب صريحة التحويل" في الصفحة 55 في الفصل 1 ، الدرس 4 من MCTS الذاتي طقم التدريب (امتحان 70-536):Microsoft® .NET Framework 2.0 تطبيق مؤسسة التنمية, هناك بالتأكيد فرق بينهما.

النظام.تحويل هو لغة مستقلة وتحويل "بين الأنواع التي تنفذ النظام.IConvertible واجهة."

(نوع) يلقي المشغل هو ج#-محددة تتميز اللغة الذي يحول "بين الأنواع التي تحدد تحويل شركات."

علاوة على ذلك, عند تنفيذ مخصص التحويلات ، نصيحة يختلف بين لهم.

في القسم بعنوان كيفية تنفيذ التحويل في أنواع مخصصة على pp.56-57 في الدرس المشار إليها أعلاه ، تحويل شركات (الصب) يقصد بها تبسيط التحويلات بين أنواع رقمية ، في حين أن تحويل() تمكن ثقافة محددة التحويلات.

الأسلوب الذي تختاره يعتمد على نوع التحويل الذي تريد القيام:

  • تعريف تحويل شركات لتبسيط تضيق وتتسع التحويل بين أنواع رقمية.

  • تنفيذ النظام.IConvertible لتمكين التحويل من خلال النظام.تحويل.استخدام هذه التقنية لتمكين ثقافة محددة التحويلات.

  • ...

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

لا ننسى غيرها من أساليب صب وتحويل المتغيرات:كما, تحليل, TryParse فضلا عن ضمني الصب بين متوافق مع أنواع البيانات.

هذا الموقع يحتوي على عينة جيدة من نواتج معظم الأساليب:C# الملاكمة و علبته

لذا وبالنظر إلى هذه العينة المتغيرات:

int i = 3, x;
long l;
string s = "5";

في الأساس يمكن أن يكون ضمنيا الصب بين اثنين متوافق أنواع:

l = i;

صراحة الصب باستخدام علبته أو كما الكلمة الرئيسية:

s = (string)i;
//or
s = i as string;

صراحة التحويلات باستخدام أساليب من النظام.تحويل:

i = System.Convert.ToInt32(s);

صراحة التحويلات باستخدام الأساليب من نوع بيانات معرف من قبل:

i = int.Parse(s);
i = int.TryParse(s, x);

صراحة التحويلات باستخدام أساليب من مثيل متغير:

s = i.ToString();

أعتقد صب هو ببساطة وسيلة لجعل المهام بين اثنين متوافق أنواع.

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

بعض معلومات جيدة أيضا على MSDN: صب نوع التحويلات

الصب هو أساسا مجرد قول من وقت التشغيل "التظاهر" الكائن هو نوع جديد.لا في الواقع تحويل أو تغيير وجوه في أي شكل من الأشكال.

تحويل ، ومع ذلك ، سيتم إجراء عمليات تحويل نوع واحد إلى آخر.

كمثال:

char caster = '5';
Console.WriteLine((int)caster);

الناتج من تلك البيانات سوف يكون 53 ، لأن كل وقت التشغيل هل هو البحث في بت نمط التعامل معها على أنها int.ما كنت في نهاية المطاف الحصول على قيمة ascii للحرف 5 بدلا من رقم 5.

إذا كنت تستخدم تحويل.ToInt32(الناعم) ومع ذلك ، سوف تحصل على 5 لأنه في الواقع يقرأ سلسلة يعدل ذلك بشكل صحيح.(أساسا أنه يعلم أن ASCII بقيمة 53 هو حقا قيمة عدد صحيح 5.)

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

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