Я знайшов спосіб викликати метод розширення з тим самим підписом, що і метод класу, однак він здається не дуже елегантним. Граючись із методами розширення, я помітив деяку поведінку без документації. Приклад коду:
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();
}
}
Що я помітив, так це те, що якщо я викликаю другий метод зсередини методу розширення, він викликає метод розширення, який відповідає підпису, навіть якщо існує метод класу, який також відповідає підпису. Наприклад, у наведеному вище коді, коли я викликаю ExtFunc (), який у свою чергу викликає ele.GetDesc (), я отримую зворотний рядок "Extension GetDesc" замість рядка "Base GetDesc", який ми очікували б.
Тестування коду:
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
Це дозволяє вам відмовлятися між методами класу та методами розширення за бажанням, але вимагає додавання повторюваних методів "наскрізного" проникнення, щоб потрапити у бажаний "обсяг". Я називаю це сферою тут через відсутність кращого слова. Сподіваюся, хтось може повідомити мене, як це насправді називається.
Ви могли здогадатися за моїми іменами методів "наскрізного проходження", я також погрався з ідеєю передати їм делегатів, сподіваючись, що один-два методи можуть виступати як прохідні для багатьох методів з однаковим підписом. На жаль, це не повинно було бути, оскільки після розпакування делегата він завжди вибирав метод класу над методом розширення, навіть всередині іншого методу розширення. "Область застосування" більше не мала значення. Я не дуже часто використовував делегатів Action та Func, хоча, можливо, хтось досвідченіший міг би зрозуміти цю частину.