Как создать экземпляр объекта с помощью частного конструктора в С#?
Я определенно помню, что где-то видел пример, используя отражение или что-то в этом роде. Это было что-то, что было связано с SqlParameterCollection
, который не может быть создан пользователем (если я не ошибаюсь). К сожалению, не могу найти его больше.
Может кто-нибудь поделиться этим трюком здесь? Не то чтобы я считаю это правильным подходом в разработке, я просто очень заинтересован в возможности сделать это.
Ответы
Ответ 1
// 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);
}
Ответ 2
Вы можете использовать одну из перегрузок Activator.CreateInstance для этого: 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()
{
}
}
Ответ 3
Это вопрос, который вы задавали?
Activator.CreateInstance с закрытым закрытым классом
Ответ 4
Если класс не принадлежит вам, то это звучит так, будто API был специально написан для предотвращения этого, а это значит, что ваш подход не соответствует требованиям авторов API. Взгляните на документы и посмотрите, есть ли рекомендуемый подход к использованию этого класса.
Если у вас есть контроль над классом и вы хотите реализовать этот шаблон, он обычно реализуется с помощью статического метода в классе. Это ключевая концепция, которая также составляет шаблон Singleton.
Например:
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(...));
Мой пример - отличный код, потому что он не демонстрирует настройки параметров параметров команды или повторного использования параметров/команд, но вы получаете идею.
Ответ 5
Это также поможет, если ваш 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);
}