qué - que es una instancia en c#
Acceso a un constructor privado desde fuera de la clase en C# (7)
Además de la respuesta de @jgauffin que indica cómo llamar a los constructores privados a través de la reflexión:
¿Es posible cambiar los modificadores del constructor privado?
Parece que estás implementando Factory Pattern en tu código. Por lo tanto, se supone que el modificador es internal
.
public class Product
{
//others can''t create instances directly outside the assembly
internal Product() { }
}
public class ProductProvider
{
//they can only get standardized products by the provider
//while you have full control to Product class inside ProductProvider
public static Product CreateProduct()
{
Product p = new Product();
//standardize the product
return p;
}
}
Metodos de extension
public static MyExt
{
public static void DoSomething(this Product p) { }
}
Llamar a p.DoSomething()
realidad es igual a MyExt.DoSomething(p)
. No está poniendo este método en clase Producto.
Si defino una clase con un constructor predeterminado privado y un constructor público que tiene parámetros, ¿cómo puedo acceder al constructor privado?
public class Bob
{
public String Surname { get; set; }
private Bob()
{ }
public Bob(string surname)
{
Surname = surname;
}
}
Puedo acceder al constructor privado a través de un método estático en la clase como este:
public static Bob GetBob()
{
return new Bob();
}
Pensé que podía acceder al constructor privado a través de un método de extensión, ya que (según mi entender) los métodos de extensión se traducen para que parezcan ser métodos estáticos en la clase, pero no puedo:
static class Fred
{
public static Bob Bobby(this Bob bob)
{
return new Bob();
}
}
Entonces, ¿cómo puedo acceder al constructor privado?
Gracias
EDITAR:
La razón por la que quería hacer esto era que quería crear pruebas para una de nuestras clases de negocios, pero no permitir que un consumidor de esta clase pudiera instanciar un objeto de manera incorrecta. Lo estoy probando, así que sé (¡espero!) En qué circunstancias las pruebas fallarán. Todavía estoy probando n00b en este momento, por lo que mi idea puede o no haber sido la "manera incorrecta" de hacer las cosas.
He cambiado mi estrategia de prueba para hacer las cosas como lo haría un consumidor de esta clase, es decir, llamar a los métodos públicos y si los métodos públicos son correctos, asumiendo que los métodos privados son correctos. Todavía preferiría probar los métodos privados, pero mi jefe está respirando por mi cuello en un entregable :-(
El método Bobby todavía está en una clase diferente, llamada Fred. Es por eso que no puedes acceder al constructor prive de la clase Bob. Lo que estás tratando de hacer no es posible con los métodos adjuntos. Incluso si pueden adjuntarse a otra clase, todavía se declaran fuera de esa clase y siguen las reglas de alcance / acceso habituales.
Hay varias formas de solucionar este problema:
Uno : hacer público el constructor. Si necesita acceder a él desde fuera de la clase, es privado (es posible que solo quiera acceder al constructor privado para realizar pruebas, en cuyo caso es un problema válido).
Dos : haga que el constructor esté protegido, luego acceda a él a través de una clase derivada:
public class Bob
{
public String Surname { get; set; }
protected Bob()
{ }
public Bob(string surname)
{
Surname = surname;
}
}
public class Fred : Bob
{
public Fred()
: base()
{
}
}
Tres : Usa la reflexión (como lo muestra el jgauffin).
Puede instanciar instancias de ese tipo a través de la reflexión.
Si está utilizando el núcleo dotnet, puede hacer lo siguiente sin tener que jugar con ningún reflejo:
YourCustomObject player = (YourCustomObject)Activator.CreateInstance(typeof(YourCustomObject),true);
Los constructores por defecto son privados por una razón. El desarrollador no lo hace privado por diversión.
Pero si aún desea utilizar el constructor predeterminado, puede obtenerlo utilizando la reflexión.
var constructor = typeof(Bob).GetConstructor(BindingFlags.NonPublic|BindingFlags.Instance, null, new Type[0], null);
var instance = (Bob)constructor.Invoke(null);
Editar
Vi tu comentario acerca de las pruebas. Nunca pruebe métodos / propiedades protegidas o privadas. Probablemente haya hecho algo mal si no puede administrar esos métodos / propiedades a través de la API pública. Quítalos o refactoriza la clase.
Editar 2
Olvidé una bandera de enlace.
public class demo
{
private demo()
{
Console.WriteLine("This is no parameter private constructor");
}
public demo(int a)
{
demo d = new demo(''c'');// u can call both private contstructors from here
demo dd = new demo();
Console.WriteLine("This is one parameter public constructor");
}
private demo(char a)
{
Console.WriteLine("This is one parameter public constructor::" + a);
}
}
class Program
{
static void Main(string[] args)
{
demo obj = new demo(7);
// demo obj = new demo(); // it will raise error
Console.ReadLine();
}
}