22 Stimmen

Ableitung des Typs einer abgeleiteten Klasse aus der statischen Methode einer Basisklasse

Ich möchte den Typ der abgeleiteten Klasse aus einer statischen Methode ihrer Basisklasse abrufen.

Wie lässt sich dies bewerkstelligen?

Danke!

class BaseClass {
  static void Ping () {
     Type t = this.GetType(); // should be DerivedClass, but it is not possible with a static method
  }
}
class DerivedClass : BaseClass {}

// somewhere in the code
DerivedClass.Ping();

39voto

Codure Punkte 734

Dies lässt sich leicht mit der Funktion Seltsam wiederkehrendes Schablonenmuster

class BaseClass<T>
    where T : BaseClass<T>
{
    static void SomeMethod() {
        var t = typeof(T);  // gets type of derived class
    }
}

class DerivedClass : BaseClass<DerivedClass> {}

die Methode aufrufen:

DerivedClass.SomeMethod();

Diese Lösung fügt eine kleine Menge an Boilerplate-Overhead hinzu, da Sie die Basisklasse mit der abgeleiteten Klasse als Vorlage verwenden müssen.

Es ist auch einschränkend, wenn Ihr Vererbungsbaum mehr als zwei Ebenen hat. In diesem Fall müssen Sie entscheiden, ob Sie das Vorlagenargument durchreichen oder den aktuellen Typ bei Aufrufen Ihrer statischen Methode auf seine Kinder übertragen wollen.

Und mit Vorlagen meine ich natürlich Generika.

17voto

Francis Gagné Punkte 52719

Wenn ich mich nicht irre, wird der Code für BaseClass.Ping() y DerivedClass.Ping() ist derselbe, also wird es nicht funktionieren, die Methode statisch zu machen, ohne ihr irgendwelche Argumente zu geben. Versuchen Sie, den Typ als Argument oder über einen generischen Typparameter zu übergeben (für den Sie eine Vererbungsbeschränkung erzwingen können).

class BaseClass {
    static void Ping<T>() where T : BaseClass {
        Type t = typeof(T);
    }
}

Sie würden es so nennen:

BaseClass.Ping<DerivedClass>();

4voto

Reed Copsey Punkte 536986

Für den Typ wird eine statische Methode definiert. Es gibt kein "this". Sie müssen dies stattdessen zu einer Instanzmethode machen:

class BaseClass {
    public void Ping() {
        Type t = this.GetType(); // This will work, since "this" has meaning here...
    }

Das können Sie dann tun:

class DerivedClass : BaseClass {}

DerivedClass instance = new DerivedClass();
instance.Ping();

3voto

Ivan Ferrer Villa Punkte 2030

Kurz gesagt, habe ich versucht, Folgendes zu beantworten ici . Sie verwendet eine Schnittstelle, um alle abgeleiteten Klassen zu vereinheitlichen und sie alle die gleiche statische Methode von der Basisklasse aufrufen zu lassen, ohne einen Typ zu übergeben.

public interface IDerived
{
}
public class BaseClass<T> where T : IDerived
{
    public static void Ping()
    {
        //here you have T = the derived type
    }
}
public class DerivedClass : BaseClass<DerivedClass>, IDerived
{
    //with : BaseClass<DerivedClass> we are defining the T above
}
public class ExampleApp
{
    public void Main()
    {
        //here we can call the BaseClass's static method through DerivedClass
        //and it will know what Type calls it
        DerivedClass.Ping();    
    }
}

0voto

mdma Punkte 55529

Es ist nicht möglich, die abgeleitete Klasse über eine statische Methode abzurufen. Ein Beispiel zur Veranschaulichung: Stellen Sie sich vor, BaseClass hat 2 Unterklassen - DerivedClass und AnotherDerivedClass - welche soll zurückgegeben werden? Im Gegensatz zu polymorphen nicht-statischen Methoden gibt es keine mögliche Assoziation mit einer abgeleiteten Klasse, die eine statische Methode einer Basisklasse aufruft - der Kompilierzeittyp und der Laufzeittyp sind bei einem statischen Methodenaufruf identisch.

Sie können entweder die Methode nicht statisch machen, so dass Sie dann den richtigen Typ über Polymorphismus erhalten, oder statische Methoden-"Überschreibungen" in den Unterklassen erstellen, z. B.

class DerivedClass : BaseClass
{
   void Ping() { 
     BaseClass.Ping();
     // or alternatively
     BaseClass.Ping(Type.GetType("DerivedClass"));
   }
}

Ihr Client-Code kann dann die Methode in der abgeleiteten Klasse aufrufen, um explizit anzugeben, dass er die Version der abgeleiteten Klasse haben möchte. Gegebenenfalls können Sie dann auch den Typ DerivedClass als Parameter an die Methode der Basisklasse übergeben, um den Kontext zu liefern, dass die Methode über die abgeleitete Klasse aufgerufen wurde.

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