4 Stimmen

Klasse erben und versteckten Basiskonstruktor aufrufen

In AssemblyOne berücksichtigen

public class A
{
    internal A (string s)
    { }
}

public class B : A
{
    internal B (string s) : base(s)
    { }
}

In AssemblyTwo

public class C : B
{
    // Can't do this - ctor in B is inaccessible
    public C (string s) : base(s)
}

Offensichtlich ist dies ein Code Geruch, aber unabhängig davon, wenn eine schlechte Idee ist es möglich, den Ctor von B aus dem Ctor von C ohne Änderung AssemblyOne aufrufen?

5voto

Jonathan Bates Punkte 1805

Ignorieren Sie die Baugruppe Zwei für den Moment. Sie könnten eine Instanz der Klasse C nicht instanziieren, weil sie von B erbt, für das es keine öffentlichen Konstruktoren gibt.

Wenn Sie also das Problem der Vererbung von Klasse C beseitigen, haben Sie immer noch ein Problem beim Erstellen von Instanzen der Klasse B außerhalb der Assembly von B aufgrund von Schutzstufen. Sie könnten jedoch Reflection verwenden, um Instanzen von B zu erstellen.

Zu Testzwecken habe ich Ihre Klassen wie folgt abgeändert:

public class A
{
    internal A(string s)
    {
        PropSetByConstructor = s;
    }

    public string PropSetByConstructor { get; set; }
}

public class B : A
{
    internal B(string s)
        : base(s)
    {
        PropSetByConstructor = "Set by B:" + s;
    }
}

Ich habe dann eine Konsolenanwendung zum Testen geschrieben:

static void Main(string[] args)
    {
       System.Reflection.ConstructorInfo ci = typeof(B).GetConstructors(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)[0];
        B B_Object = (B)ci.Invoke(new object[]{"is reflection evil?"});

        Console.WriteLine(B_Object.PropSetByConstructor);

        Console.ReadLine();
    }

Ich würde nicht empfehlen, dies zu tun, es ist einfach schlechte Praxis. Ich nehme an, in allen Dingen gibt es Ausnahmen, und die Ausnahme hier ist möglicherweise mit einer 3rd-Party-Bibliothek, die Sie nicht erweitern können zu tun. Dies würde Ihnen eine Möglichkeit geben, zu instanziieren und zu debuggen, wenn nicht erben.

2voto

SLaks Punkte 832502

Dies ist auch mit Reflexion nicht möglich.

Wenn eine Klasse keine zugänglichen Konstruktoren hat, gibt es keine Möglichkeit, eine Klasse zu erstellen, die sie erbt.

1voto

Adam Sills Punkte 16598

Nein, Sie müssen AssemblyOne ändern.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X