Лямбда-выражение свойства получает дополнительный Convert(p=›p.Property)

У меня есть проблема, когда в некоторых случаях (кажется, где тип свойства - bool) лямбда-выражение используется для ссылки на свойство. Я использую это, чтобы получить его имя; проблема в том, что иногда выражение модифицируется, чтобы иметь дополнительную функцию Convert().

e.g.

GetPropertyName<TSource>(Expression<Func<TSource, object>> propertyLambda) {...}

var str = GetPropertyName<MyObject>(o=>o.MyBooleanProperty);

Что происходит, так это то, что propertyLambda выглядит как Convert(o.MyBooleanProperty), а не o.MyBooleanProperty, как я ожидал.


person sambomartin    schedule 25.06.2012    source источник
comment
Извините, а в чем именно вопрос? Откуда взялась функция Convert?   -  person Philip Daubmeier    schedule 26.06.2012
comment
Можем ли мы увидеть код реализации GetPropertyName   -  person fenix2222    schedule 26.06.2012
comment
хорошо, спасибо, Джон. но частью вопроса были какие-нибудь идеи [почему это происходит]? - как упомянул Филип, это больше похоже на утверждение без вопроса в конце. но цените ваши усилия.   -  person sambomartin    schedule 26.06.2012


Ответы (1)


Добавляется Convert, потому что o.MyBooleanProperty — это bool, но результатом должен быть объект. Если бы вы сделали свой метод универсальным как в типе исходного объекта, так и в типе результата, тогда не было бы Convert:

GetPropertyName<TSource, TResult>(Expression<Func<TSource, TResult>> propertyLambda)

К сожалению, это означает, что вы должны указать TResult явно:

GetPropertyName<MyObject, bool>(o => o.MyBooleanProperty)

Если вы не хотите этого делать, вам придется найти способ вывести MyObject или избежать его необходимости.

Например, если текущий объект MyObject (и вы находитесь в методе экземпляра), вы можете изменить свой код так, чтобы он принимал Func<TResult>:

GetPropertyName(() => this.MyBooleanProperty)

Или вы можете включить другой параметр типа TSource, который поможет вам сделать вывод о типе:

GetPropertyName(myObject, o => o.MyBooleanProperty)
person svick    schedule 26.06.2012
comment
большое спасибо @svick - учитывая ваш последний пример GetPropertyName(myObject, o => o.MyBooleanProperty) - как бы выглядело объявление функции, мне, очевидно, нужно было бы добавить параметр объекта? Кроме того, возможно ли создать расширение, которое предоставляет метод расширения GetPropertyName на основе этого примера GetPropertyName(() => this.MyBooleanProperty)? - person sambomartin; 26.06.2012
comment
Объявление последней опции будет выглядеть примерно так: GetPropertyName<TSource, TResult>(TSource obj, Expression<Func<TSource, TResult>> propertyLambda). И я не уверен, что вы подразумеваете под методом расширения, в этом случае вам не нужен экземпляр, это может быть обычный статический метод. - person svick; 26.06.2012