我找到了一种方法来调用与类方法具有相同签名的扩展方法,但是它似乎不是很优雅。在使用扩展方法时,我注意到一些未记录的行为。示例代码:
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 代表,所以也许更有经验的人可以弄清楚这部分。