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

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

  •  01-07-2019
  •  | 
  •  

سؤال

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

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


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

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

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

المحلول

لا يمكنك تقييد T معينة منشئ التوقيع غير فارغة منشئ, ولكن يمكنك تقييد T أن لدينا مصنع الأسلوب مع توقيع المطلوب:

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

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

ولكن أود أن أقترح ربما باستخدام مختلف creational نمط مثل مصنع مجردة عن هذا السيناريو.

نصائح أخرى

لا.إذا كنت لم تمر في المعلمات, ثم هل يمكن أن تحد من نوع المعلمة تتطلب parameterless منشئ.ولكن إذا كنت بحاجة إلى تمرير الوسائط كنت خارجا من الحظ.

where T : MyBaseClass, new()

يعمل فقط w/ parameterless منشئ العام.أبعد من ذلك, إلى المنشط.CreateInstance (وهي في الحقيقة ليست بهذا السوء).

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

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

public void ThisIsANoNo<T>() 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<MyClass>();
            ThisIsANoNo<MyBaseClass>();
        }

        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<T>() where T : MyBaseClass
        {
            MyBaseClass foo = new MyBaseClass("whoops!");
        }
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top