Wie kann ich verhindern, dass ein Basiskonstruktor aus durch einen inheritor in C # aufgerufen wird?

StackOverflow https://stackoverflow.com/questions/159296

Frage

Ich habe eine (schlecht geschrieben) Basisklasse, die ich in einem Proxy-Objekt wickeln möge. Die Basisklasse ähnelt der folgenden:

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

   public BaseClass(int someValue) {}

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

und mein Proxy ähnelt:

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

Ohne den „Fakeout“ Konstruktor wird der Basiskonstruktor erwartet aufgerufen werden. Aber mit ihm, erwartete ich es nicht aufgerufen werden. So oder so, ich brauche entweder eine Art und Weise keine Basisklassenkonstruktoren anrufen oder eine andere Art und Weise, um effektiv Proxy diese (böse) Klasse.

War es hilfreich?

Lösung

Wenn Sie nicht ausdrücklich jegliche Konstruktor in der Basisklasse aufrufen kann, wird der Konstruktor implizit aufgerufen parameterlos werden. Es gibt keinen Weg darum herum, eine Klasse ohne einen Konstruktor nicht instanziiert kann aufgerufen werden.

Andere Tipps

Es gibt eine Möglichkeit, ein Objekt ohne Aufruf jeder Instanzkonstruktoren zu erstellen.

Bevor Sie fortfahren, sehr sicher, dass Sie es auf diese Weise tun wollen. 99% der Zeit, dies ist die falsche Lösung.

Dies ist, wie Sie es tun:

FormatterServices.GetUninitializedObject(typeof(MyClass));

Nennen Sie es anstelle der Konstruktor des Objekts. Es wird erstellt und kehren Sie eine Instanz ohne Konstrukteurs-Aufruf oder Feld initializers.

Wenn Sie ein Objekt in WCF deserialisieren, verwendet es diese Methode, um das Objekt zu erstellen. Wenn dies geschieht, Konstrukteure und sogar Feld initializers werden nicht ausgeführt werden.

Mindestens 1 Ctor hat aufgerufen werden. Der einzige Weg, um es ich sehe, ist Containment. Lassen Sie die Klasse innerhalb oder Verweisen auf die andere Klasse.

Wenn das, was Sie wollen, ist zu nicht rufen Sie eine der beiden Basisklassenkonstruktoren, dies nicht getan werden kann.

C # Klasse Konstrukteure müssen Basisklassenkonstruktoren nennen. Wenn Sie rufen Sie nicht eine ausdrücklich, base () wird angedeutet, . In Ihrem Beispiel, wenn Sie es nicht angeben, die gleiche wie die Basisklasse Konstruktor aufzurufen, ist:

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

Wenn Sie es vorziehen, die andere Basisklassenkonstruktor zu verwenden, können Sie verwenden:

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

So oder so, eine der beiden genannt, explizit oder implizit sein.

Ich glaube nicht, dass Sie den Konstruktor aufrufen umgehen können. Aber man könnte so etwas tun:

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
   }
} 

Wenn Sie eine BaseClassProxy erstellen Objekt, das es braucht eine Instanz zu schaffen, die es Basisklasse ist, so dass Sie den Basisklassenkonstruktor anrufen müssen, was können Sie doo ist eine wählen weicht zu nennen, wie:

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

den zweiten Konstruktor aufzurufen anstelle des ersten

Ich fürchte, dass die Basis nicht Aufruf Konstruktor ist nicht Option.

ich am Ende so etwas wie dies zu tun:

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

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

Das hat mich um einige der schlechten Praktiken der Basisklasse.

Konstrukteure sind öffentlich von der Natur. keinen Konstruktor verwenden und eine andere für den Bau verwenden und machen es private.so Sie eine Instanz ohne paramtersand Aufruf, der für den Aufbau Ihrer Objektinstanz funktionieren würde erstellen.

In Ordnung, hier ist eine hässliche Lösung für das Problem einer Klasse der Konstruktoren einer anderen Klasse erbt, die ich nicht zu arbeiten, einige von ihnen erlauben wollte. Ich habe gehofft, zu vermeiden, mit dies in meiner Klasse, aber hier ist es:

Hier ist meine Klasse Konstruktor:

public MyClass();
{
   throw new Exception("Error: Must call constructor with parameters.");
}

OK jetzt wurden Sie gewarnt, dass es war hässlich. Keine Beschwerden bitte!

Ich wollte die minimalen Parameter von meinem Haupt-Konstruktor zwingen, zumindest ohne den geerbten Basiskonstruktor ohne Parameter ermöglicht.

Ich glaube auch, dass, wenn Sie einen Konstruktor erstellen und stellen nicht die. Basis (), nachdem er, dass es nicht den Basisklassenkonstruktor nennt Und wenn Sie erstellen Konstrukteure für alle diejenigen, in der Basisklasse und bietet die gleichen genauen Parameter für sie in der Hauptklasse, dass es nicht passieren wird. Aber dies kann sehr mühsam sein, wenn Sie viele Konstrukteure in der Basisklasse haben!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top