11 Stimmen

Übergabe einer Erweiterungsmethode an eine Methode, die einen Delegaten erwartet. Wie funktioniert das?

Bei der Arbeit habe ich also eine API verwendet, die wir nicht selbst geschrieben haben, und eine der Methoden nahm einen Delegaten. Aus irgendeinem Grund kam mir die Idee, dass ich eine Erweiterungsmethode habe, die zu dieser Signatur passt, und ich fragte mich, ob sie funktionieren würde. Ich war mir sicher, dass es nicht funktionieren würde, aber zu meiner großen Überraschung funktionierte es doch. Erlauben Sie mir, das zu demonstrieren:

Nehmen wir an, ich habe diese Klassen:

public interface IMyInterface
{

}

public class MyClass : IMyInterface 
{ 

}

public static class Extensions
{
    public static string FuncMethod(this IMyInterface imy, int x)
    {
        return x.ToString();
    }
}

Nehmen wir an, ich habe irgendwo eine Methodensignatur, die wie folgt aussieht:

    private static void Method(Func<int, string> func)
    {

    }

Meine Erweiterungsmethode (sieht so aus) entspricht dieser Signatur, aber wir alle wissen, dass Erweiterungsmethoden nur Schall und Rauch sind, also ist es wirklich nicht mit dieser Signatur übereinstimmen. Dennoch kann ich dies sicher tun:

var instance = new MyClass();
Method(instance.FuncMethod);

Meine Frage ist: Wie funktioniert das? Was generiert der Compiler für mich, um dies akzeptabel zu machen. Die eigentliche Signatur der Extension-Methode nimmt eine Instanz von IMyInterface aber die Func nicht, was passiert hier für mich hinter den Kulissen?

11voto

SLaks Punkte 832502

Instanzmethoden sind als versteckte Methoden implementiert this Parameter.

Wenn Sie einen Instanzdelegaten aus einer Erweiterungsmethode erstellen, wird die versteckte this Parameter wird als erster normaler Parameter an die Methode übergeben.

Beachten Sie, dass dies nicht mit Werttypen möglich ist .

6voto

Amy B Punkte 104656

Ich weiß nicht genau, was der Compiler tut, um diese Szenarien zu ermöglichen, aber die Erwartungen scheinen angemessen. Vielleicht hilft dieses Code-Beispiel dabei, das Konzept zu begreifen.

MyClass instance = new MyClass();
Func<int, string> f1 = instance.FuncMethod;
Func<int, string> f2 = (i) => instance.FuncMethod(i);
Func<int, string> f3 = (i) => Extensions.FuncMethod(instance, i);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X