programacion - herencia en c#
¿Cómo crear una instancia de un objeto con un constructor privado en C#? (5)
Definitivamente recuerdo haber visto en alguna parte un ejemplo de hacerlo utilizando la reflexión o algo así. Era algo que tenía que ver con SqlParameterCollection que no es creable por un usuario (si no me equivoco). Lamentablemente no puedo encontrarlo por más tiempo.
¿Alguien puede por favor compartir este truco aquí? No es que lo considere un enfoque válido en el desarrollo, solo estoy muy interesado en la posibilidad de hacer esto.
¿Es esta la pregunta que buscabas? Activator.CreateInstance con clase privada sellada
Puede usar una de las sobrecargas de Activator.CreateInstance para hacer esto: Activator.CreateInstance(Type type, bool nonPublic)
Use true
para el argumento no público. Porque true
coincide con un constructor predeterminado público o no público; y false
coincide solo con un constructor público predeterminado.
Por ejemplo:
class Program
{
public static void Main(string[] args)
{
Type type=typeof(Foo);
Foo f=(Foo)Activator.CreateInstance(type,true);
}
}
class Foo
{
private Foo()
{
}
}
Si la clase no es una de las suyas, entonces parece que la API fue escrita deliberadamente para evitar esto, lo que significa que es posible que su enfoque no sea lo que pretendían los escritores de la API. Eche un vistazo a los documentos y vea si hay un enfoque recomendado para usar esta clase.
Si tiene control sobre la clase y desea implementar este patrón, entonces generalmente se implementa a través de un método estático en una clase. Este es un concepto clave que conforma el patrón Singleton, también.
Por ejemplo:
public PrivateCtorClass
{
private PrivateCtorClass()
{
}
public static PrivateCtorClass Create()
{
return new PrivateCtorClass();
}
}
public SomeOtherClass
{
public void SomeMethod()
{
var privateCtorClass = PrivateCtorClass.Create();
}
}
El material SqlCommandParameter es un buen ejemplo. Esperan que crees parámetros llamando a cosas como esta:
var command = IDbConnnection.CreateCommand(...);
command.Parameters.Add(command.CreateParameter(...));
Mi ejemplo no es un gran código porque no demuestra la configuración de las propiedades de los parámetros de los comandos ni la reutilización de los parámetros / comandos, pero se entiende la idea.
También ayudará si su Type
es private
o 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);
}
// 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);
}