La plupart des réponses ici semblent passer à côté de l'essentiel. Le polymorphisme peut être utilisé non seulement entre les instances, mais aussi entre les types. Ceci est souvent nécessaire, lorsque nous utilisons des génériques.
Supposons que nous ayons un paramètre de type dans une méthode générique et que nous devions effectuer une opération avec lui. Nous ne voulons pas faire d'instantanéité, car nous ne connaissons pas les constructeurs.
Par exemple :
Repository GetRepository<T>()
{
//need to call T.IsQueryable, but can't!!!
//need to call T.RowCount
//need to call T.DoSomeStaticMath(int param)
}
...
var r = GetRepository<Customer>()
Malheureusement, je ne peux proposer que des alternatives "moches" :
-
Utiliser la réflexion Moche et qui bat l'idée des interfaces et du polymorphisme.
-
Créer une classe d'usine complètement distincte
Cela pourrait augmenter considérablement la complexité du code. Par exemple, si nous essayons de modéliser des objets de domaine, chaque objet aurait besoin d'une autre classe de référentiel.
-
Instanciez et appelez ensuite la méthode de l'interface souhaitée.
Cela peut être difficile à mettre en œuvre même si nous contrôlons la source des classes, utilisées comme paramètres génériques. La raison en est que, par exemple, nous pourrions avoir besoin que les instances soient uniquement dans un état bien connu, "connecté à la base de données".
Exemple :
public class Customer
{
//create new customer
public Customer(Transaction t) { ... }
//open existing customer
public Customer(Transaction t, int id) { ... }
void SomeOtherMethod()
{
//do work...
}
}
afin d'utiliser l'instantination pour résoudre le problème de l'interface statique, nous devons faire la chose suivante :
public class Customer: IDoSomeStaticMath
{
//create new customer
public Customer(Transaction t) { ... }
//open existing customer
public Customer(Transaction t, int id) { ... }
//dummy instance
public Customer() { IsDummy = true; }
int DoSomeStaticMath(int a) { }
void SomeOtherMethod()
{
if(!IsDummy)
{
//do work...
}
}
}
Cela est évidemment laid et complique inutilement le code de toutes les autres méthodes. Évidemment, ce n'est pas non plus une solution élégante !
6 votes
Eh bien, Java 8 l'a fait ( stackoverflow.com/questions/23148471/ ).
1 votes
Voyez comment vous pouvez combiner un comportement statique avec l'héritage ou la mise en œuvre d'une interface : stackoverflow.com/a/13567309/880990
1 votes
IListItem.ScreenName() => ScreenName()
(en utilisant la syntaxe C# 7) implémentera explicitement la méthode de l'interface en appelant la méthode statique. Les choses se gâtent lorsque vous ajoutez l'héritage à cela, cependant (vous devez réimplémenter l'interface).2 votes
Je veux juste que tout le monde sache que l'attente est maintenant terminée ! C# 8.0 a des méthodes d'interface statiques : dotnetfiddle.net/Lrzy6y (bien qu'ils fonctionnent un peu différemment de la façon dont OP voulait qu'ils fonctionnent - vous n'êtes pas obligé de les implémenter)