سؤال

وأنا بالتأكيد أتذكر رؤية مكان مثال ذلك باستخدام الانعكاس أو شيء من هذا. لقد كان شيئا له علاقة SqlParameterCollection وهي ليست creatable من قبل المستخدم (إذا لم أكن مخطئا). للأسف لا يمكن العثور عليه لفترة أطول.

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

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

المحلول

// the types of the constructor parameters, in order
// use an empty Type[] array if the constructor takes no parameters
Type[] paramTypes = new Type[] { typeof(string), typeof(int) };

// the values of the constructor parameters, in order
// use an empty object[] array if the constructor takes no parameters
object[] paramValues = new object[] { "test", 42 };

TheTypeYouWantToInstantiate instance =
    Construct<TheTypeYouWantToInstantiate>(paramTypes, paramValues);

// ...

public static T Construct<T>(Type[] paramTypes, object[] paramValues)
{
    Type t = typeof(T);

    ConstructorInfo ci = t.GetConstructor(
        BindingFlags.Instance | BindingFlags.NonPublic,
        null, paramTypes, null);

    return (T)ci.Invoke(paramValues);
}

نصائح أخرى

ويمكنك استخدام واحدة من الزائدة من على Activator.CreateInstance لقيام بذلك: <لأ href = "https://msdn.microsoft.com/en-us/library/he47tyc4(v= vs.110) .ASPX "يختلط =" noreferrer "> Activator.CreateInstance(Type type, bool nonPublic)

استخدم true الوسيطة nonPublic. لأن true مباريات منشئ افتراضي العام أو غير العام. وfalse مباريات فقط منشئ افتراضي العام.

وعلى سبيل المثال:

    class Program
    {
        public static void Main(string[] args)
        {
            Type type=typeof(Foo);
            Foo f=(Foo)Activator.CreateInstance(type,true);
        }       
    }

    class Foo
    {
        private Foo()
        {
        }
    }

هل هذا هو السؤال الذي كان بعد؟ Activator.CreateInstance مع الطبقة مختومة الخاص

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

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

وعلى سبيل المثال:

public PrivateCtorClass
{
    private PrivateCtorClass()
    {
    }

    public static PrivateCtorClass Create()
    {
        return new PrivateCtorClass();
    }
}

public SomeOtherClass
{
    public void SomeMethod()
    {
        var privateCtorClass = PrivateCtorClass.Create();
    }
}

والاشياء SqlCommandParameter هو مثال جيد. انهم يتوقعون منك أن إنشاء معلمات حسب تسمية الأشياء مثل هذا:

var command = IDbConnnection.CreateCommand(...);
command.Parameters.Add(command.CreateParameter(...));

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

ووسوف يساعد أيضا إذا Type الخاص بك هو private أو internal:

 public static object CreatePrivateClassInstance(string typeName, object[] parameters)
    {
        Type type = AppDomain.CurrentDomain.GetAssemblies().
                 SelectMany(assembly => assembly.GetTypes()).FirstOrDefault(t => t.Name == typeName);
        return type.GetConstructors()[0].Invoke(parameters);
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top