سؤال

هل من الممكن بناء كائن مع مُنشئه الداخلي داخل طريقة عامة؟

public abstract class FooBase { }

public class Foo : FooBase {
   internal Foo() { }
}

public static class FooFactory {
    public static TFooResult CreateFoo<TFooResult>()
    where TFooResult : FooBase, new() {
        return new TFooResult();
    }
}

FooFactory يقيم في نفس التجميع Foo. تدعو الفصول الدراسية طريقة المصنع مثل هذا:

var foo = FooFactory.CreateFoo<Foo>();

يحصلون على خطأ في وقت الترجمة:

يجب أن يكون "Foo" نوعًا غير متكبر مع مُنشئ بدون معلمة من أجل استخدامه كمعلمة "tfootype" في النوع العام أو الطريقة "foOfactory.createfoo ()"

هل هناك أي طريقة للالتفاف حول هذا؟

حاولت أيضا:

Activator.CreateInstance<TFooResult>(); 

هذا يثير نفس الخطأ في وقت التشغيل.

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

المحلول

يمكنك إزالة new() القيد والعودة:

//uses overload with non-public set to true
(TFooResult) Activator.CreateInstance(typeof(TFooResult), true); 

على الرغم من أن العميل يمكن أن يفعل ذلك أيضًا. هذا ، ومع ذلك ، عرضة لأخطاء وقت التشغيل.

هذه مشكلة صعبة لحلها بطريقة آمنة لأن اللغة لا تسمح بإعلان مُنشئ مجردة.

نصائح أخرى

يجب أن تحتوي حجة النوع عام مُنشئ بدون معلمة. عند استخدامها مع قيود أخرى ، يجب تحديد القيد الجديد () أخيرًا.

http://msdn.microsoft.com/en-us/library/d5x73970.aspx

تحرير: لا ، إذا كنت تستخدم القيد الجديد () ، فلا يمكنك تمرير هذا الفصل ، إذا لم تستخدم القيد الجديد () يمكنك محاولة استخدام التفكير لإنشاء مثيل جديد

public static TFooResult CreateFoo<TFooResult>()
where TFooResult : FooBase//, new()
        {
            return (TFooResult)typeof(TFooResult).GetConstructor(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance, null, new Type[] {}, null).Invoke(new object[]{});
            //return new TFooResult();
        }

يمكن أن يكون هناك عدد قليل من عمليات العمل على النحو التالي ، لكنني لا أعتقد أنك تريد أن تذهب بهذه الطريقة!

  • ضع بيان التبديل داخل المصنع الذي سيقوم بإنشاء المثيل بناءً على نوع المعلمة النوع.

  • سيتم تسجيل كل تطبيق ملموس لـ Foobase مع Foofactory تمرير طريقة المصنع لإنشاء الذات. لذلك سوف تستخدم الفووكتور القاموس الداخلي

  • التمديد على السطر المماثل باستثناء التعيين بين معلمة النوع وتنفيذ الخرسانة سيكون رمزًا خارجيًا (ملف XML ، التكوين وما إلى ذلك). يمكن أن تساعد حاويات IOC/DI هنا.

public class GenericFactory
{
    public static T Create<T>(object[] args)
    {
        var types = new Type[args.Length];
        for (var i = 0; i < args.Length; i++)
            types[i] = args[i].GetType();

        return (T)typeof(T).GetConstructor(types).Invoke(args);
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top