Tôi đã tìm ra cách để gọi một phương thức mở rộng có cùng chữ ký với một phương thức lớp, tuy nhiên nó có vẻ không được thanh lịch cho lắm. Khi thử nghiệm với các phương pháp mở rộng, tôi nhận thấy một số hành vi không có giấy tờ. Mã mẫu:
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();
}
}
Điều tôi nhận thấy là nếu tôi gọi phương thức thứ hai từ bên trong một phương thức mở rộng, nó sẽ gọi phương thức mở rộng phù hợp với chữ ký ngay cả khi có một phương thức lớp cũng khớp với chữ ký. Ví dụ trong đoạn mã trên, khi tôi gọi ExtFunc (), lần lượt gọi ele.GetDesc (), tôi nhận được chuỗi trả về "Extension GetDesc" thay vì chuỗi "Base GetDesc" mà chúng tôi mong đợi.
Kiểm tra mã:
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
Điều này cho phép bạn chuyển qua lại giữa các phương thức lớp và phương thức mở rộng theo ý muốn, nhưng yêu cầu bổ sung các phương thức "truyền qua" trùng lặp để đưa bạn vào "phạm vi" mà bạn mong muốn. Tôi gọi nó là phạm vi ở đây vì thiếu một từ tốt hơn. Hy vọng rằng ai đó có thể cho tôi biết nó thực sự được gọi là gì.
Bạn có thể đoán được tên phương thức "truyền qua" của tôi. Tôi cũng đã đùa giỡn với ý tưởng chuyển các đại diện cho chúng với hy vọng rằng một hoặc hai phương thức có thể hoạt động như một phương thức truyền cho nhiều phương thức có cùng một chữ ký. Thật không may, nó đã không được như sau khi ủy nhiệm được giải nén, nó luôn chọn phương thức lớp thay vì phương thức mở rộng ngay cả từ bên trong một phương thức mở rộng khác. "Phạm vi" không còn quan trọng nữa. Mặc dù vậy, tôi đã không sử dụng các đại diện Action và Func cho lắm nên có lẽ ai đó có kinh nghiệm hơn có thể hiểu được điều đó.