Делегат из extension method group
Интересно, я ожидал от компилятора C# в таком коде скрытого замыкания:
static class Foo {
static void Bar(this string source) { }
static void Main() {
System.Action boo = "abc".Bar;
}
}
На самом деле компилятор сгенерировал здесь точно такой же msil, как если бы метод Bar()
был настоящим методом уровня экземпляра типа System.String
, сохранив экземпляр строки в экземпляре делегата - так же, как сохраняет и автоматически “подставляет” в качестве первого параметра скрытый от пользователя this
.
Было бы интересно иметь противоположную возможность - позволить создавать из методов уровня экземпляра делегаты с произвольным this
-параметром, допустив указание произвольного экземплярного метода без экземпляра соответствующего типа (и даже нет проблем пересечения с именами статических методов):
System.Func<string, int> boo = System.String.Length;
Однако очевидная проблема данной фичи проявляется в случае использования виртуальных методов:
System.Func<Foo, int> boo = Foo.GetHashCode;
Из какого именно метода делать делегат? Из метода Foo.GetHashCode()
? Что, если тип Foo
не переопределяет метод GetHashCode()
- брать реализацию Object.GetHashCode
? Что, если первым параметром делегата передадут наследника Foo
, имеющего свою реализацию GetHashCode()
- вызывать эту реализацию (тогда делегат никогда не будет указывать на какой-то конкретный метод) или использовать реализацию типа Foo
(что позволяет на наследниках вызовы Foo.GetHashCode()
, которые могут быть недопустимы)? Допускать-ли такую запись, если метод GetHashCode()
объявлен абстрактным? Кстати, Object.GetHashCode()
, как и любой другой виртуальный метод, можно переопределить и одновременно сделать абстрактным, путём комбинирования модификаторов abstract
и override
- что делать в таком случае?
Вообщем, мягко говоря, сомнительная фича получается :)