Таким образом на работе я использовал 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
не так, что происходит здесь для меня негласно?
Методы экземпляра реализованы как принимающие скрытый этот
параметр.
Когда вы создаете делегат экземпляра из метода расширения, скрытый параметр this
передается методу в качестве первого нормального параметра.
Обратите внимание, что это невозможно сделать с типами значений .
Я не знаю точно, что делает компилятор, чтобы разрешить эти сценарии, но ожидания кажутся разумными. Возможно, этот образец кода поможет разобраться с этой концепцией.
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);