2017-01-05 4 views
2

Mit der abstrakten folgenden Klasse:C# abstrakter allgemeiner Methodenaufruf

public abstract class A 
{ 
    public static string MyMethod() 
    { 
     return "a"; 
    } 
} 

Warum kann ich nicht gebaut abgeleitete abstrakte Klasse:

public class B<T> where T : A 
{ 
    public void AnotherMethod() 
    { 
     var S1 = base.MyMethod(); // not allowed 
     var S2 = T.MyMethod();  // not allowed 
    } 
} 

Ich verstehe nicht, warum da MyMethod wird verfügbar sein in Typ T.

+0

In C# werden statische Methodenaufrufe immer statisch zur Kompilierungszeit aufgelöst. Statische Methoden sind nicht an der Vererbung beteiligt. – recursive

+2

Warum nicht 'var S2 = A.MyMethod();', da Sie 'A' oben wissen? –

+1

'Basis.MyMethod() 'würde nie funktionieren, weil B nicht A erbt, es hat einen Typparameter, der auf eine Implementierung von A beschränkt ist, wo der Kommentar von recursive kommt. – Phaeze

Antwort

3

Es gibt zwei Missverständnisse in Ihrer Frage, die gemeinsam verhindern, dass beide Versuche funktionieren.

Zuerst ist Ihre B Klasse in keiner Weise von der A Klasse abgeleitet, Sie haben nur gesagt, dass es einen generischen Parameter benötigt, der von A erben muss.

Zweitens, wenn der Benutzer @recursive wies darauf hin, statische Methoden nicht teilnehmen bei der Vererbung so MyMethod würde immer nur verfügbar sein, wie A.MyMethod()

Sie mindestens Ihre erste Versuch Arbeit machen können, wenn Sie den statischen Modifikator entfernen und B erben von A, anstatt Generika zu verwenden.

// Removed the static modifier 
public abstract class A 
{ 
    public string MyMethod() 
    { 
     return "a"; 
    } 
} 

// Made B inherit directly from A 
public class B : A 
{ 
    public void AnotherMethod() 
    { 
     var S1 = base.MyMethod(); //base technically isn't required 
    } 
} 
+0

Ich verstehe jetzt; Ich hatte den Eindruck, dass B: A irgendwie die gleichen Eigenschaften wie B ergab, wo T: A – Thomas

+0

@Thomas, Awesome, froh, dass ich helfen konnte – Phaeze

3

Abgesehen von der Tatsache, dass A.MyMethod statisch ist, die bei der Vererbung teilnehmen statisch, da irgendetwas nicht eindeutig nicht funktioniert, auch wenn Sie es noch nicht funktionieren wird es nicht statisch gemacht. Zum Beispiel wird dies entweder nicht:

public abstract class A { 
    public string MyMethod() { 
     return "a"; 
    } 
} 

public class B<T> where T : A { 
    public void AnotherMethod() { 
     var S1 = base.MyMethod(); // Line 1 
     var S2 = T.MyMethod();  // Line 2 
    } 
} 

Warum?

Sie where T : A sagen, die diese Art bedeutet T hat eine abgeleitete Art von A sein. Ihre Klasse B<T ist kein abgeleiteter Typ von A, daher funktioniert Zeile 1 nicht.

Aber warum funktioniert Zeile 2 nicht?

T ist ein Typ und wenn TA ist vererben, dann Objekte vom Typ T wird, das tun können. Wenn Sie es wie folgt geändert, dann wird es funktionieren:

public abstract class A { 
    public string MyMethod() { 
     return "a"; 
    } 
} 

public class B<T> where T : A { 
    public void AnotherMethod(T t) { 
     t.MyMethod(); 
    } 
} 

public class C : A { 

} 

public class BClosed : B<C> { 
    public void Foo(C c) { 
     c.MyMethod(); 
     this.AnotherMethod(c); 
    } 
} 

In dem obigen Code, CA die Ihre Einschränkung war ableitet. Dann BClosed schließt die generische Art sagen T ist C so können Sie jetzt MyMethod von A und AnotherMethod Ihrer generischen anrufen.

Wenn Sie eine generische Klasse haben, sollten Sie den generischen Typ verwenden, sonst sehe ich die Verwendung nicht. Das ist nutzlos, da es keinen generischen Code enthält:

+0

Das verdeutlicht es sehr! Vielen Dank! – Thomas

+0

Sehr schönes Detail, um die generische Seite der Frage zu decken. – Phaeze