Ответ на ваш вопрос будет отрицательным. По крайней мере, что касается C #.
Почему? Допустим, у вас есть следующий объект:
public class Foo
{
public int SomeProp { get; set; }
}
вы знаете, что под капотом компилятор автоматически сгенерирует для вас int get_SomeProp () и void set_SomeProp (int value) (плюс поле поддержки), поэтому вы сможете сделать это:
var someMethod = foo.get_SomeProp;
и вы можете - почти. Вы получаете эту ошибку от компилятора: «не может явно вызвать оператор или метод доступа». Так что без размышлений или обертки, вы SOL. Может быть. Я говорю, может быть, потому что только потому, что C # не позволяет вам обращаться с геттером или сеттером как с реальным методом, это не значит, что какой-то другой язык .NET не может. Например, я могу написать это в F #:
namespace PassSetter
module mucker =
let muckWithFoo (aFoo:Foo) =
aFoo.set_SomeProp
и теперь muckWithFoo - это функция, объявленная как Foo -> (int-> unit), которая эквивалентна методу, который возвращает делегат void d (int value). По сути, вы можете использовать другой модуль, чтобы при необходимости нарушить ограничение компилятора C #. Я выбрал F # только потому, что у меня под рукой есть компилятор, но держу пари, что вы можете сделать это и с C ++ / CLI.
Основное различие между этим и оберткой заключается в том, что даже если вам все еще нужно написать обертку для каждого типа, для которого вы хотите получить делегата, эта обертка в конечном итоге не будет присоединена к последнему делегату.
Я не знаю, в чем ваша проблема с ограничением «без отражения» - это то, что вы работаете в среде, которая запрещает отражение, или вы считаете, что вы настолько ограничены в производительности, что не можете себе позволить? использовать отражение. Если это последнее, то вам доступно еще несколько опций, которые дают вам гораздо лучшую производительность, чем просто рефлексия для получения метода набора свойств и последующего его вызова (эффективного вызова по имени).