2008-10-01 6 views
16

Tengo una clase base (mal escrita) que quiero envolver en un objeto proxy. La clase base similar al siguiente:¿Cómo puedo evitar que un heredero invoque un constructor base en C#?

public class BaseClass : SomeOtherBase 
{ 
    public BaseClass() {} 

    public BaseClass(int someValue) {} 

    //...more code, not important here 
} 

y, mi representante se asemeja:

public BaseClassProxy : BaseClass 
{ 
    public BaseClassProxy(bool fakeOut){} 
} 

Sin el constructor "Fakeout", se espera que el constructor base a ser llamado. Sin embargo, con eso, esperaba que no se llamara. De cualquier manera, o necesito una forma de no llamar a ningún constructor de la clase base, o de alguna otra forma para proxy eficaz esta clase (mal).

Respuesta

18

Si no llama explícitamente a ningún constructor en la clase base, el constructor sin parámetros se llamará implícitamente. No hay forma de evitarlo, no puedes instanciar una clase sin que se llame a un constructor.

+1

En realidad, si lees mi comentario a continuación, hay una manera, aunque no lo recomendaría en la mayoría de los casos. –

+0

Esta respuesta es simplemente incorrecta. Especialmente a la luz de la otra respuesta. – Kobor42

6

Se debe llamar al menos a 1 ctor. La única forma de evitarlo es la contención. Tener la clase dentro o haciendo referencia a la otra clase.

+0

Este es el camino que me está dando más resultados. ¡Gracias! – casademora

1

Tengo miedo de que el constructor de llamadas no base no sea una opción.

1

Cuando se crea un BaseClassProxy objeto que necesita para crear una instancia de su clase base, por lo que necesita para llamar al constructor de la clase base, lo que puede doo es elegir wich a quien llamar, como:

public BaseClassProxy (bool fakeOut) : base (10) {} 

Para llamar al segundo constructor en lugar del primero

4

No creo que pueda moverse llamando al constructor. Pero se puede hacer algo como esto:

public class BaseClass : SomeOtherBase 
{ 
    public BaseClass() {} 

    protected virtual void Setup() 
    { 
    } 
} 

public BaseClassProxy : BaseClass 
{ 
    bool _fakeOut; 
    protected BaseClassProxy(bool fakeOut) 
    { 
     _fakeOut = fakeOut; 
     Setup(); 
    } 

    public override void Setup() 
    { 
     if(_fakeOut) 
     { 
      base.Setup(); 
     } 
     //Your other constructor code 
    } 
} 
5

Si lo que desea es no llamada de cualquiera de los dos constructores de clase base, esto no se puede hacer.

Los constructores de la clase C# deben llamar a los constructores de la clase base. Si no llama a uno explícitamente, base() está implícito. En su ejemplo, si no se especifica qué constructor de la clase base para llamar, es lo mismo que:

public BaseClassProxy : BaseClass 
{ 
    public BaseClassProxy() : base() { } 
} 

Si prefiere utilizar otro constructor de la clase base, que puede utilizar:

public BaseClassProxy : BaseClass 
{ 
    public BaseClassProxy() : base(someIntValue) { } 
} 

De cualquier manera, uno de los dos se llamará, explícita o implícitamente.

0

que terminé haciendo algo como esto:

public class BaseClassProxy : BaseClass 
{ 
    public BaseClass BaseClass { get; private set; } 

    public virtual int MethodINeedToOverride(){} 
    public virtual string PropertyINeedToOverride() { get; protected set; } 
} 

Esto me llevó alrededor de algunas de las malas prácticas de la clase base.

+2

El constructor predeterminado implícito sigue llamando al constructor sin parámetros de BaseClass. – recursive

46

Hay una manera de crear un objeto sin llamar cualquier constructor de instancia.

Antes de continuar, asegúrese de que quiere hacerlo de esta manera. El 99% de las veces esta es la solución incorrecta.

Así es como se hace:

FormatterServices.GetUninitializedObject(typeof(MyClass)); 

llaman en lugar del constructor del objeto. Creará y le devolverá una instancia sin llamar a ningún constructor o inicializador de campo.

Cuando deserializa un objeto en WCF, utiliza este método para crear el objeto. Cuando esto sucede, los constructores e incluso los inicializadores de campo no se ejecutan.

+9

Eso es loco. ¡Todo mi mundo está patas arriba! – recursive

+2

Welp, eso resolvió mi problema! Intentando evitar las llamadas al DB del constructor de un objeto padre al ejecutar pruebas unitarias en una clase heredada. – Tarka

+2

FormatterServices.GetUninitializedObject (typeof (MyClass)); todavía llamará a constructores estáticos, sin embargo. –

0

constructores son públicos por naturaleza. no use un constructor y use otro para la construcción y hágalo privado. De este modo, crearía una instancia sin parámetros y llamaría a esa función para construir su instancia de objeto.

0

Este es mi primer intento descuidado en esta respuesta. Vólalo y le prestaré más atención.

No estoy seguro de lo que está tratando de lograr, pero parece que le faltan interfaces. Podrías escoger y elegir qué interfaces tienen sentido para tu necesidad. Si esto es así para la prueba, entonces usaría algo como A.Fake para probar. Si proporciona más detalles sobre lo que está tratando de lograr. Probablemente podría ser más útil.

public interface IExtractedFromSomeOtherBase{ 
    // this could also be an interface that the other base already implements. 
    /* extracted stuff here */ 
} 
public interface IBaseClass { 
    /* stuff */ 
} 
public interface IBaseClassProxy { 
    /* stuff */ 
} 
public class BaseClass : 
    SomeOtherBase, IExtractedFromSomeOtherBase, IBaseClass 
{ 
    public BaseClass() {} 

    public BaseClass(int someValue) {} 

    //...more code, not important here 
} 
and, my proxy resembles: 

public BaseClassProxy : BaseClass, IBaseClassProxy 
{ 
    public BaseClassProxy(bool fakeOut){} 
} 
Cuestiones relacionadas