C# 如何解析接口的“虚拟”目标?

mar*_*zzz 1 c# c++ interface vtable

假设我在C++,并且我有这个伪接口(abstract class仅包含pure virtual methods):

class IErrorLog
{
public:
    virtual bool closeLog() = 0;
};

class FileErrorLog : public IErrorLog
{
public:
    FileErrorLog(){}
    ~FileErrorLog(){}

    bool closeLog() { 
        std::cout << "Close FileErrorLog" << std::endl; 
        return true;
    }
};

int main()
{   
    FileErrorLog fileErrorLog;
    IErrorLog *log = &fileErrorLog;
    log->closeLog();
}
Run Code Online (Sandbox Code Playgroud)

我所知closeLog使用 的动态类型IErrorLog称为对 的动态vtable类型进行去虚拟化FileErrorLog并选择所需的目标函数(closeLog()指针)。

由于 inC#并不是interfaces真正被认为是类,所以当我做这样的事情时:

interface IErrorLog {
    void closeLog ();
}

public class FileErrorLog : IErrorLog
{
    public FileErrorLog() {}

    public void closeLog() {
        Console.WriteLine("Close FileErrorLog");
    }        
}

public class Program
{
    public static void Main(string[] args)
    {
        IErrorLog log = new FileErrorLog();
        log.closeLog();
    }
}
Run Code Online (Sandbox Code Playgroud)

C# 将如何解决这个问题closeLog()?是同样的机制吗?

因为这里IErrorLog log已经不再是了abstract class。它是原生类型。因此,我不认为log是指向 的指针FileErrorLog

你能给我解释一下吗?

Eri*_*ert 5

C# 将如何解决 closeLog() 问题?

运行时将使用实现定义的机制正确解析调用。

对于接口来说,这种机制相当复杂,并且存在有趣的性能影响。

是同样的机制吗?

它与某些 C++ 编译器用于不同类型系统的机制相同吗?几乎可以肯定不是。

然而,这些机制是相似的,因为有一些函数指针表挂在对象实例指针上,并且在运行时进行查找以进行方法分派。

因此,我不认为 log 是指向 FileErrorLog 的指针。

我假设你的意思是“托管指针”;在 C# 中,我们希望您将引用描述为“引用”;非托管指针有很大不同。

由于托管指针不同是错误的,因此您有一个错误的信念。你从错误信念中得出的任何结论都是不合理推理的结果,并且是不可靠的。

根据您的问题和一些评论,您的核心错误信念似乎是对象引用的内存中表示取决于用于存储引用的变量的类型。这种信念是 100% 完全错误的,所以现在就停止相信它。在 CLR 中,引用转换是表示保留转换

如果对类类型 C 的对象的引用由数字 0x12345678 表示,然后将其转换为对由 C 实现的接口 I 的引用,则表示形式仍然是 0x12345678。

有没有类似于 learncpp 源代码的用于理解 C# 行为的教程?

本站不用于推荐教程。