سؤال

أود أن أكون قادرا على إعلان وظيفة

void foo(<any value type>[] data){}

في C # 2.0. إذا أعلنت ذلك

void foo(ValueType[] data){}

إنها تجمع، ولكن بعد ذلك يتم التعامل مع العناصر الموجودة في البيانات [] كما لو أنها مستمدة من object, ، على سبيل المثال لا أستطيع أن أقول شيئا مثل

fixed (void* pData = data){}

أرغب في تجنب تناول الفراغ * كمعلمة - أريد فقط أن أكون قادرا على قبول أي صفيف من نوع القيمة ثم القيام بأشياء غير مدارة بها.

ETA: أيضا، هذا لديه نفس المشكلة:

public static unsafe void foo<T>(T[] data) where T:struct{
  fixed(void *p = data){}
}

في حال كنت أتساءل. فشل ثابت لأنه يعامل كوعي مدار - CS0208، لا يمكن أن يعلن مؤشرا إلى نوع مدار. انظر "مم" أدناه. أعتقد أنه على حق ... ربما لا يمكن القيام به.

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

المحلول

لا أعتقد أن هذا ممكن باستخدام C #. لا ترث الهياكل (مهما فضفاضة) من SYSTEM.VALETYPE حتى بعد تجميع الوقت حتى لا تتمكن من مطابقة توقيع طريقة FOO عبر تعدد الأشكال. الأجداد هي أيضا خارج وفقا لمواصفات اللغة:

"نوع غير مدار هو أي نوع ليس نوع مرجعي، نوع المعلمة, أو نوع الهيكل العام ولا يحتوي على حقول لنوعه ليس نوعا غير مدار. "

لهذا السبب لا يمكنك اتخاذ عنوان T [] بغض النظر عن قيد الهيكل.

هل يمكن أن تعلن نوع الهيكل (على سبيل المثال، بار) كوسيطة FOO، ترجمة التعليمات البرمجية، وتغيير توقيع الطريقة على مستوى IL:

.method private hidebysig static void Foo(valuetype [mscorlib]System.ValueType[] args) cil managed

ثم الدعوة كذلك:

IL_0020: call void ConsoleApplication1.Program::Foo(valuetype [mscorlib]System.ValueType[])

بينما كنت قادرا على تشغيل البرنامج الناتج، لا أعرف أي نوع من الآثار الجانبية التي لدى هذا. أيضا، حتى إذا كنت تستطيع الرجوع إلى الوظيفة المعدلة، فلن تتمكن من الاتصال به من C # لأن الهياكل مرة أخرى لا ترث من SYSTEM.VALETYPE حتى بعد التجميع حتى لا يتطابق توقيع الطريقة.

نصائح أخرى

public void foo<T>(params T[] args) where T : struct {
}
public void SomeMethod() {
    foo(1, 2, 3, 4);
}

يجب ألا تضطر إلى إدخال المعلمة العامة لأن المحول البرمجي سيستلم من النوع من المعلمة الأولى من FOO.

هذا سيعمل:

    public static void foo(System.Array data)
    {

    }

    static void Main(string[] args)
    {
        foo(new int[10]);  
    }

لا ينفذ أن الصفيف عبارة عن مجموعة من أنواع القيمة، لكنها ستعمل.

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