2017-01-05 2 views
2

Avec la classe abstraite suivante:C# appel abstrait méthode générique

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

Pourquoi ne puis-je construit cette classe abstraite dérivée:

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

Je ne comprends pas pourquoi depuis maméthode sera être disponible dans le type T.

+0

En C#, les appels de méthodes statiques sont toujours résolus statiquement, au moment de la compilation. Les méthodes statiques ne participent pas à l'héritage. – recursive

+2

Pourquoi pas 'var S2 = A.MonMethod();', puisque vous connaissez 'A' ci-dessus? –

+1

'base.MyMethod() 'ne fonctionnerait jamais parce que B n'hérite pas de A, il a un paramètre de type qui est restreint à une implémentation de A, où le commentaire de récursif arrive. – Phaeze

Répondre

3

Il y a deux idées fausses dans votre question qui empêchent collectivement vos deux tentatives de fonctionner.

D'abord, votre classe B n'est en aucun cas dérivée de la classe A, vous avez seulement dit qu'il faut un paramètre générique qui doit hériter de A.

deuxième comme @recursive utilisateur a fait remarquer, les méthodes statiques ne participent pas à l'héritage si MyMethod serait que jamais disponible A.MyMethod()

Vous pouvez faire au moins votre premier travail de tentative si vous supprimez le modificateur statique et faire B hérite de A au lieu d'utiliser des génériques.

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

Je comprends maintenant; J'étais sous l'impression que B: A a cédé d'une manière ou d'une autre les mêmes propriétés que B où T: A – Thomas

+0

@Thomas, Awesome, content d'avoir pu aider – Phaeze

3

Mis à part le fait que A.MyMethod est statique, ce qui clairement fonctionnera pas car rien statique ne prend pas part à l'héritage, même si vous l'avez fait pas statique, il ne fonctionne toujours pas. Par exemple, cela ne fonctionnera pas non plus:

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

Pourquoi?

Vous dites where T : A ce qui signifie que le type T doit être un type dérivé de A. Votre classe B<T n'est pas un type dérivé de A, donc la ligne 1 ne fonctionnera pas.

Mais pourquoi la ligne 2 ne fonctionne-t-elle pas?

T est un type et si T est héritant A, les objets de type T seront en mesure de le faire. Si vous avez changé comme ça, il fonctionnera:

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

Dans le code ci-dessus, C dérive A qui était votre restriction. Puis BClosed ferme le type générique en disant T est C alors maintenant vous pouvez appeler MyMethod de A et AnotherMethod de votre générique.

De même, lorsque vous avez une classe générique, vous devez utiliser le type générique sinon je ne vois pas l'utilisation. Donc, cela est inutile car il n'a pas de code générique:

public class B<T> where T : A { 
    public void AnotherMethod() { 

    } 
} 
+0

Cela le clarifie beaucoup! Merci! – Thomas

+0

Très joli détail pour couvrir le côté générique de la question. – Phaeze