C #: يلقي كائن إلى نوع رقم غير موقعي باستخدام Generics

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

  •  13-09-2019
  •  | 
  •  

سؤال

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

لكنه لا يعمل من أجل أنواع غير موقعة (ULONG، UINT). أدناه يوجد رمز بسيط يظهر ما أريد القيام به. إذا قمت بتغيير نوع UL VAR من Ulong إلى Int، فإنه يعمل بشكل جيد.

هل لدى أي شخص فكرة؟

public class console
{

    public static void CastIt<T>(object value, out T target)
    {
        target = (T) value;
    }

    public static void Main()
    {
        ulong ul;
        string str;
        int i;
        DateTime dt;

        object ul_o = (object) 2;
        object str_o = (object) "This is a string";
        object i_o = (object)1;
        object dt_o = (object) DateTime.Now;

        Console.WriteLine("Cast");

        CastIt(ul_o, out ul);
        CastIt(str_o, out str);
        CastIt(i_o, out i);
        CastIt(dt_o, out dt);

        Console.WriteLine(ul);
        Console.WriteLine(str);
        Console.WriteLine(i);
        Console.WriteLine(dt.ToString());
    }

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

المحلول

كما يقول أندرو، فإن المشكلة هي أنه لا يمكنك unbox من محاصر int ل ulong.

خيارين:

1) مربع أ ulong في حين أن:

object ul_o = (object) 2UL;

أو

ulong tmp = 2;
object ul_o = tmp;

2) اتخاذ CastIt<T> استعمال Convert.ChangeType:

public static void CastIt<T>(object value, out T target)
{
    target = (T) Convert.ChangeType(value, typeof(T));
}

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

نصائح أخرى

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

إذا كان هذا هو في الحقيقة ما تريد القيام به، فبدلا من مجرد ممثلين مستقيم، استخدم هذا:

target = (T)Convert.ChangeType(value, typeof(T));

لا يسمح لك CLR بإلقاء هذه الطريقة لأن نوع القيمة المحاصر الخاص بك هو في الواقع INT:

object ul_o = (object)2;

عندما تحاول أن يلقي إلى ulong لا يمكنك لأنك لا تستطيع Unbox int مباشرة إلى ulong.

أعتقد أن ما تريده هو أشبه أكثر (غير مختبر، ولكن صحيح اتجاهي) ...

public static void CastIt<T>( object value ) where T : IConvertable
{
  return ( T )Convert.ChangeType( value , typeof( T ) );
}

تحرير: سحرها Skeet! :)

هذه ليست حقا إجابة لسؤالك؛ أردت فقط أن أذكر أنه إذا كنت تستخدم .NET 3.5، لينك إلى مجموعات البيانات يتضمن التعليمات البرمجية الوظائف مثل ما تقوم به. ستكون طريقة التمديد المحددة حقلu003CT> () على فئة datarow.

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