Почему деревья выражений безопаснее, чем отражения? - PullRequest
14 голосов
/ 11 ноября 2010

В этот ответ на вопрос о самом быстром способе определения, содержит ли свойство заданный атрибут, пользователь Дарин Димитров утверждает, что деревья выражений безопаснее, чем отражения. Это правда, и если да, то почему это так?

Ответы [ 4 ]

13 голосов
/ 11 ноября 2010

Потому что, когда вы ищете свое поле (как в этом вопросе), вы используете строковое представление "Id". Как только оно будет изменено, ваше отражение рухнет.

Дарин предлагает статическую типизацию:

Expression<Func<Program, int>> expression = p => p.Id;

Вы это видите? Это интересная, но не очень известная особенность компилятора C # 4.0: автоматически строить дерево выражений из лямбда-выражения и приводить его к Expression<T> Итак, позже вы можете пройти его и получить MemberInfo из Id. Но это не так универсально, как Reflection, потому что вы не можете искать по string.

5 голосов
/ 11 ноября 2010

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

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

Изменить, чтобы уточнить - MemberInfo.GetCustomAttributes является вызовом отражения.

http://msdn.microsoft.com/en-us/library/system.reflection.memberinfo.getcustomattributes(VS.71).aspx

1 голос
/ 11 ноября 2010

Из моего ограниченного знания .NET способ дерева выражений, похоже, выполняет проверку типов.

0 голосов
/ 08 марта 2018

Если мы говорим о безопасности типов и нарушении кода при переименовании свойств, например, дерево выражений «преимущество» сводится на нет теперь, когда у нас есть более новые функции C #, такие как nameof ():

Способ дерева выражений (быллучше перед nameof ()):

Expression<Func<YourClass, int>> expression = p => p.Id;
var memberExpression = (MemberExpression)expression.Body;
var property = ((PropertyInfo)memberExpression.Member);

GetProperty от имени (было плохо до nameof ()):

var property = typeof(YourClass).GetProperty(nameof(YourClass.Id));

Строковый ввод в GetProperty не был безопасным, посколькужестко запрограммирован на «Id», и когда вы переименуете свойство Id, ваш код будет прерываться во время выполнения, если вы не забудете заменить эту строку, а также.

Это сделало деревья выражений более безопасными, потому что вы использовали реальное имясвойства.

Но теперь, когда у нас есть nameof (), используемая строка фактически является именем свойства во время компиляции, и если вы переименуете свойство, и вы / ваша IDE «забудете» переименоватьв приведенном выше фрагменте также код будет сломан во время компиляции.

Так что теперь старый "плохой путь", на мой взгляд, более лаконичен и, вероятно, работает как минимум лучше.л, так как вам не нужен дополнительный кастинг.

...