C# 3.0 : Pourquoi il ne faut pas utiliser les extension methods
Dans la lignée de mon message "Pourquoi ne faut il plus utiliser l'héritage de classe", voici la suite. Par contre, celui-ci est très sérieux.
Les méthodes d'extension ont été introduites dans C# 3.0 comme une solution pour permettre au mapping syntaxique (plus d'info sur ça ici) de LINQ de fonctionner correctement avec IEnumerable, sans avoir à modifier IEnumerable (ce qui poserait d'énormes problèmes au code existant). Malheureusement si elles sont pratiques pour ce cas précis (et sont effectivement la meilleure solution), dans 95% des cas, elles posent de graves problèmes de versionning, et doivent donc être utilisées avec une extrême prudence. Voici un exemple du problème.
Supposons qu'un éditeur tierce (ou même un autre développeur de votre équipe) développe un assembly x.dll. Dans cet assembly nous avons une classe MyClass :
public
class
MyClass
{
// ...
}
Vous décidez d'écrire une méthode d'extension pour MyClass qui s'appelle par exemple Add :
public
static
void
Add(
this
MyClass
target,
object
item)
{
// ...
}
Vous utilisez cette méthode d'extension un peu partout dans votre code.
L'assembly x.dll passe alors en version 2.0, et il se trouve que l'éditeur ajoute une méthode Add à MyClass, qui a un comportement différent de votre méthode d'extension (ce qui sera toujours le cas, à moins d'une grosse coïncidence) :
public
class
MyClass
{
// ...
public
void
Add(
object
item)
{
// ...
}
}
Le code va compiler sans problème (vous n'aurez même pas de Warning), mais le comportement de votre code sera changé. Si vous utilisez la méthode Add pour un objet de type MyClass, c'est maintenant la méthode d'instance qui sera appelée au lieu de la méthode d'extension.
Ce problème très grave n'a pas vraiment de solution. Il y a quelques usages à respecter pour réduire le risque, mais il existera toujours :
- N'utilisez les méthodes d'extensions qu'en dernier recours
- Ne définissez des méthodes d'extension que pour des types qui ont relativement peu de chances de changer, comme des types basiques du Framework .NET (comme IEnumerable par exemple).
D'autres blogs parlent de ce problème :
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :