[英]Why does the C# compiler insert an explicit interface implementation?
我遇到了一個奇怪的C#邊緣案例,我正在尋找一個好的解決方案。
有一個我無法控制的類看起來像這樣:
namespace OtherCompany
{
public class ClassIDoNotControl
{
public void SomeMethod(string argument)
{
Console.WriteLine((new StackFrame(1).GetMethod().Name));
}
}
}
我想從這個類中的一類我做控制繼承。 另外,我想在其上指定一個接口:
interface IInterfaceIDoControl
{
void SomeMethod(string argument);
}
class ClassIDoControl : OtherCompany.ClassIDoNotControl, IInterfaceIDoControl
{
}
如果所有這些文件都在同一個程序集中,那么一切都很好:
namespace MyCompany
{
class Program
{
static void Main(string[] args)
{
IInterfaceIDoControl i = new ClassIDoControl();
i.SomeMethod("Hello World!"); // Prints "Main"
}
}
}
但是,如果我將“ClassIDoNotControl”移動到另一個程序集中,我就達不到我的預期。 相反,我看到輸出暗示額外堆棧幀的“MyCompany.IInterfaceIDoControl.SomeMethod”。
原因是在C#編譯器下,將“ClassIDoControl”更改為如下所示:
class ClassIDoControl : OtherCompany.ClassIDoNotControl, IInterfaceIDoControl
{
void IInterfaceIDoControl.SomeMethod(string argument)
{
base.SomeMethod(argument);
}
}
有沒有辦法避免這個編譯器生成的額外的間接層與明確實現的接口?
簡短回答: CLR要求實現接口方法的所有方法都必須是虛擬的( Ecma 335 Partition II Section 12.1)。
答案很長:
如果基類中的方法已經是虛擬的,則不需要額外的任何內容:接口方法可以綁定到它。
如果基類中的方法不是虛擬的,而是在同一個程序集中,那么偷偷摸摸的編譯器實際上使它成為虛擬和最終的 。 Reflector證實了這一點。 (“final”是C#中“密封”的CLR術語。)
如果基類中的方法不是虛擬的並且在另一個程序集中,那么顯然編譯器不能這樣做,因為它無法修改已經編譯的程序集。 因此,此處唯一的選擇是插入實現接口方法的重定向方法。 與實現接口方法的所有方法一樣,它也標記為虛擬和最終 。
所以你最后一個問題的答案是“有沒有辦法避免這種情況?”,遺憾的是沒有。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.