سؤال

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

public static implicit operator Currency(decimal d)
{
     return new Currency(d);
}

هذا يعمل بشكل جيد عندما أستخدمه في الكود. ومع ذلك ، عندما يكون لدي هذا:

foreach (PropertyInfo p in props)
{
     p.SetValue(this, table.Rows[0][p.Name], null);
}

إنه يلقي enbumentException يفيد أنه لا يمكن تحويله من النظام. أنا مرتبك لأنه يعمل بشكل جيد في أي ظرف آخر.

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

المحلول

أنا فكر في تحتاج إلى إلغاء توصيل القيمة أولاً في table.Rows[0][p.Name] ك decimal.

بعبارات أخرى:

foreach (PropertyInfo p in props)
{
     if (p.PropertyType == typeof(Currency))
     {
         Currency c = (decimal)table.Rows[0][p.Name];
         p.SetValue(this, c, null);
     }
     else
     {
         p.SetValue(this, table.Rows[0][p.Name], null);
     }
}

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

نصائح أخرى

لسوء الحظ ، لا يتم استخدام مشغلي التحويل المعرفة من قبل المستخدم بواسطة وقت التشغيل ؛ يتم استخدامها فقط من قبل المترجم في وقت الترجمة. لذلك إذا كنت تأخذ بقوة decimal وتعيينه إلى طائرة قوية Currency, ، سيقوم المترجم بإدخال مكالمة إلى مشغل التحويل الخاص بك والجميع سعداء. ومع ذلك ، عندما تتصل SetValue كما تفعل هنا ، يتوقع منك وقت التشغيل أن تمنحه قيمة من النوع المناسب ؛ ليس لدى وقت التشغيل أي فكرة عن وجود مشغل التحويل هذا ، ولن يسميه أبدًا.

أفترض ذلك table من النوع DataTable في الكود الخاص بك ، لذلك يقوم المفهرس الأول بإرجاع أ DataRow, والثاني يعيد object. ثم PropertyInfo.SetValue يأخذ أيضا object كحجة ثانية. في أي مكان في هذا الرمز يحدث الممثلين في الكود, ، وهذا هو السبب في عدم تطبيق مشغل التحويل الزائد.

بشكل عام ، يتم تطبيقه فقط عندما تكون أنواع ثابتة معروفة (نسيان dynamic في C# 4.0 للحظة). لا يتم تطبيقه عند الملاكمة والملاكمة. في هذه الحالة ، فارس على DataRow صناديق القيمة ، و PropertyInfo.SetValue يحاول إلغاء الازدهار إلى نوع مختلف - ويفشل.

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

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