كيفية إنشاء مثيل كائن مع منشئ الخاص في C #؟
-
22-08-2019 - |
سؤال
وأنا بالتأكيد أتذكر رؤية مكان مثال ذلك باستخدام الانعكاس أو شيء من هذا. لقد كان شيئا له علاقة 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);
}