Q:

How C# resolve interface's "virtual" target? 

Let say I'm in C++, and I have this pseudo-interface (an abstract class with only 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();
}

For what I've learned, closeLog, using the dynamic type of IErrorLog, is called devirtualizing that vtable of FileErrorLog and selecting the desidered target function (closeLog() pointer). 
Since in C#'s interfaces are not really considered classes, when I do somethings like this:
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();
    }
}

how C# will resolve that closeLog()?  Is it the same mechanism?  
Because here IErrorLog log isn't an abstract class anymore.  Its a native type.  Thus, I don't think log is a pointer to FileErrorLog. 
Can you explain it to me? 

A:

how C# will resolve that closeLog()?  

The runtime will resolve the call correctly by using an implementation-defined mechanism. 
This mechanism is quite complicated in the case of interfaces, and there are interesting performance implications. 

Is it the same mechanism?  

Is it the same mechanism as some C++ compiler uses for a different type system?   Almost certainly not. 
The mechanisms however are similar, in that there are tables of function pointers hung off of the object instance pointer, and lookups are done at runtime to do the method dispatching. 

Thus, I don't think log is a pointer to FileErrorLog. 

I assume you mean "managed pointer"; in C# we would prefer you to characterize references as "references"; unmanaged pointers are very different. 
Since it is false that the managed pointers differ, you have a false belief.  Anything that you've concluded from that false belief is the result of unsound reasoning and is not reliable. 
Based on your question and a number of your comments, your core false belief seems to be that the in-memory representation of a reference to an object depends on the type of the variable that is being used to store the reference.  This belief is 100% completely false, so stop believing it right now.   In the CLR, reference conversions are representation preserving conversions.   
If a reference to an object of class type C is represented by the number 0x12345678, and you then convert that to a reference to interface I implemented by C, the representation is still 0x12345678. 

Any tutorial similar to that learncpp source for understanding C# behaviour? 

This site is not for recommending tutorials.