J'ai trouvé un moyen d'invoquer une méthode d'extension avec la même signature qu'une méthode de classe, mais cela ne semble pas très élégant. En jouant avec les méthodes d'extension, j'ai remarqué un comportement non documenté. Exemple de code:
public static class TestableExtensions
{
public static string GetDesc(this ITestable ele)
{
return "Extension GetDesc";
}
public static void ValDesc(this ITestable ele, string choice)
{
if (choice == "ext def")
{
Console.WriteLine($"Base.Ext.Ext.GetDesc: {ele.GetDesc()}");
}
else if (choice == "ext base" && ele is BaseTest b)
{
Console.WriteLine($"Base.Ext.Base.GetDesc: {b.BaseFunc()}");
}
}
public static string ExtFunc(this ITestable ele)
{
return ele.GetDesc();
}
public static void ExtAction(this ITestable ele, string choice)
{
ele.ValDesc(choice);
}
}
public interface ITestable
{
}
public class BaseTest : ITestable
{
public string GetDesc()
{
return "Base GetDesc";
}
public void ValDesc(string choice)
{
if (choice == "")
{
Console.WriteLine($"Base.GetDesc: {GetDesc()}");
}
else if (choice == "ext")
{
Console.WriteLine($"Base.Ext.GetDesc: {this.ExtFunc()}");
}
else
{
this.ExtAction(choice);
}
}
public string BaseFunc()
{
return GetDesc();
}
}
Ce que j'ai remarqué, c'est que si j'appelais une deuxième méthode à partir d'une méthode d'extension, elle appellerait la méthode d'extension qui correspondait à la signature même s'il y avait une méthode de classe qui correspondait également à la signature. Par exemple dans le code ci-dessus, lorsque j'appelle ExtFunc (), qui à son tour appelle ele.GetDesc (), j'obtiens la chaîne de retour "Extension GetDesc" au lieu de la chaîne "Base GetDesc" que nous attendons.
Tester le code:
var bt = new BaseTest();
bt.ValDesc("");
//Output is Base.GetDesc: Base GetDesc
bt.ValDesc("ext");
//Output is Base.Ext.GetDesc: Extension GetDesc
bt.ValDesc("ext def");
//Output is Base.Ext.Ext.GetDesc: Extension GetDesc
bt.ValDesc("ext base");
//Output is Base.Ext.Base.GetDesc: Base GetDesc
Cela vous permet de rebondir entre les méthodes de classe et les méthodes d'extension à volonté, mais nécessite l'ajout de méthodes "pass-through" en double pour vous amener dans la "portée" que vous désirez. J'appelle cela portée ici faute d'un meilleur mot. J'espère que quelqu'un pourra me dire comment cela s'appelle réellement.
Vous avez peut-être deviné par mes noms de méthodes «pass-through» que j'ai aussi caressé l'idée de leur passer des délégués dans l'espoir qu'une seule méthode ou deux puisse agir comme un relais pour plusieurs méthodes avec la même signature. Malheureusement, ce n'était pas comme une fois que le délégué a été décompressé, il a toujours choisi la méthode de classe plutôt que la méthode d'extension, même à partir d'une autre méthode d'extension. "Portée" n'avait plus d'importance. Cependant, je n'ai pas beaucoup utilisé les délégués Action et Func, alors peut-être que quelqu'un de plus expérimenté pourrait comprendre cette partie.