Намерих начин да извикам метод на разширение със същия подпис като метод на клас, но не изглежда много елегантен. Когато си играех с методите за разширение, забелязах известно недокументирано поведение. Примерен код:
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, така че може би някой по-опитен би могъл да разбере тази част.
person
DanK
schedule
23.03.2019