هل هناك طريقة أنيقة لتفعيل نوع متغير مع المعلمات؟

هذا ليس قانوني:

public class MyBaseClass
{
  public MyBaseClass() {}
  public MyBaseClass(object arg) {}
}


public void ThisIsANoNo() where T : MyBaseClass
{
  T foo = new T("whoops!");
}

للقيام بذلك ، يجب عليك القيام ببعض الانعكاس على كائن الكتابة لـ T أو يجب عليك استخدام Activator.CreateInstance. كلاهما سيئة جدا. هل هناك طريقة أفضل؟

0
وأضاف
الآراء: 1

4 إجابة

where T : MyBaseClass, new()

يعمل فقط ث/منشئ العام غير المعلمة. بعد ذلك ، العودة إلى activator.CreateInstance (التي ليست سيئة حقا).

0
وأضاف
ليس بطريقة عامة.
وأضاف المؤلف Darren Kopp, مصدر

أستطيع أن أرى أن لا يعمل.

لكن ما الذي يمنعك من فعل هذا؟

public void ThisIsANoNo() where T : MyBaseClass
{
  MyBaseClass foo = new MyBaseClass("whoops!");
}

وبما أن كل شيء سيرث من MyBaseClass ، فسيكون MyBaseClass هو الصحيح؟

لقد حاولت ذلك وهذا يعمل.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            ThisIsANoNo();
            ThisIsANoNo();
        }

        public class MyBaseClass
        {
            public MyBaseClass() { }
            public MyBaseClass(object arg) { }
        }

        public class MyClass :MyBaseClass
        {
            public MyClass() { }
            public MyClass(object arg, Object arg2) { }
        }

        public static void ThisIsANoNo() where T : MyBaseClass
        {
            MyBaseClass foo = new MyBaseClass("whoops!");
        }
    }
}
0
وأضاف
T هو امتداد MyBaseClass. يمكنك إنشاء نسخة جديدة من MyBaseClass ، ولكن لا يمكنك "تحويل" إلى T ، لأنه ليس T. بالإضافة إلى ذلك ، فإن تطبيق ThisIsANoNo ، بينما يحتوي على توقيع عام ، لا يكون جديدًا اكتب متغير.
وأضاف المؤلف Will, مصدر
إنه فراغ لا يعيد أي شيء. والفريق يمكن أن يصلح ذلك.
وأضاف المؤلف chrissie1, مصدر
Abe حاولت ذلك ويعمل.
وأضاف المؤلف chrissie1, مصدر
ماذا يحدث إذا كان لديك فئة مشتقة تحتوي فقط على مُنشئ يأخذ وسيطتين؟
وأضاف المؤلف Abe Heidebrecht, مصدر
لن تقوم هذه الطريقة بإرجاع الكائنات من النوع T ، فقط الكائنات من النوع MyBaseClass.
وأضاف المؤلف Matt Howells, مصدر

كلا. إذا لم تكن تمرر في المعلمات ، فيمكنك تقييد نمط الكتابة الخاص بك لتطلب منشئ غير بارز. ولكن ، إذا كنت بحاجة إلى تمرير الحجج ، فأنت محظوظ.

0
وأضاف

لا يمكنك تقييد T للحصول على توقيع مُنشئ معين بخلاف مُنشئ فارغ ، ولكن يمكنك تقييد T للحصول على طريقة مصنع بالتوقيع المطلوب:

public abstract class MyBaseClass
{
    protected MyBaseClass() {}
    protected abstract MyBaseClass CreateFromObject(object arg);
}

public void ThisWorksButIsntGreat() where T : MyBaseClass, new()
{
    T foo = new T().CreateFromObject("whoopee!") as T;
}

ومع ذلك ، أود أن أقترح ربما استخدام نمط مختلف من الإبداع مثل Abstract Factory لهذا السيناريو.

0
وأضاف