Saya telah menemukan cara untuk memanggil metode ekstensi dengan tanda tangan yang sama sebagai metode kelas, namun tampaknya tidak terlalu elegan. Saat bermain-main dengan metode ekstensi, saya melihat beberapa perilaku yang tidak terdokumentasi. Kode sampel:
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();
}
}
Apa yang saya perhatikan adalah jika saya memanggil metode kedua dari dalam metode ekstensi, itu akan memanggil metode ekstensi yang cocok dengan tanda tangan bahkan jika ada metode kelas yang juga cocok dengan tanda tangan. Misalnya dalam kode di atas, ketika saya memanggil ExtFunc (), yang pada gilirannya memanggil ele.GetDesc (), saya mendapatkan string kembali "Extension GetDesc" alih-alih string "Base GetDesc" yang kita harapkan.
Menguji kode:
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
Hal ini memungkinkan Anda untuk bolak-balik antara metode kelas dan metode ekstensi sesuka hati, tetapi memerlukan penambahan metode "pass-through" duplikat untuk membawa Anda ke "cakupan" yang Anda inginkan. Saya menyebutnya ruang lingkup di sini karena kurangnya kata yang lebih baik. Mudah-mudahan seseorang bisa memberi tahu saya apa sebenarnya namanya.
Anda mungkin telah menebak dengan nama metode "pass-through" saya bahwa saya juga bermain-main dengan gagasan meneruskan delegasi kepada mereka dengan harapan bahwa satu atau dua metode dapat bertindak sebagai pass-through untuk beberapa metode dengan tanda tangan yang sama. Sayangnya itu tidak terjadi setelah delegasi diekstrak, ia selalu memilih metode kelas daripada metode ekstensi bahkan dari dalam metode ekstensi lain. "Cakupan" tidak lagi penting. Saya belum banyak menggunakan delegasi Action dan Func, jadi mungkin seseorang yang lebih berpengalaman dapat memahami bagian itu.