Передача дополнительного метода к методу, ожидающему делегата. Как это работает?

Таким образом на работе я использовал API, который мы не записали, и один из методов взял делегата. По той или иной причине идея прибыла ко мне, что у меня есть дополнительный метод, который соответствует той подписи, таким образом, я задавался вопросом, будет ли это работать. Я был уверен, что это не будет, но к моему большому удивлению, это сделало. Позвольте мне демонстрировать:

Скажите, что у меня есть эти классы:

public interface IMyInterface
{

}

public class MyClass : IMyInterface 
{ 

}

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

Теперь скажем, у меня есть сигнатура метода где-нибудь, которая похожа на это:

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

    }

Теперь мой дополнительный метод (похож на него) соответствует той подписи, но все мы знаем, что дополнительные методы являются просто обманом, таким образом, это действительно не соответствует той подписи. Все же я могу безопасно сделать это:

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

Мой вопрос, как это работает? Что генерирует компилятор, чтобы я сделал это приемлемым. Фактическая подпись Дополнительного метода берет экземпляр IMyInterface, но Func не так, что происходит здесь для меня негласно?

11
задан BFree 19 July 2010 в 20:37
поделиться

2 ответа

Методы экземпляра реализованы как принимающие скрытый этот параметр.

Когда вы создаете делегат экземпляра из метода расширения, скрытый параметр this передается методу в качестве первого нормального параметра.

Обратите внимание, что это невозможно сделать с типами значений .

11
ответ дан 3 December 2019 в 07:36
поделиться

Я не знаю точно, что делает компилятор, чтобы разрешить эти сценарии, но ожидания кажутся разумными. Возможно, этот образец кода поможет разобраться с этой концепцией.

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);
5
ответ дан 3 December 2019 в 07:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: