Передать выражение
В данный момент вы не передаете свойство в Method
. Вы передаете значение объекта. Метод не знает, что такое исходное свойство, и поэтому не может установить его в null.
Чтобы обойти это, вы можете передать Expression
, представляющее свойство вместо значения свойства. Затем ваш метод может проанализировать выражение и сделать все необходимое, включая чтение и установку значения.
Поэтому вместо этого
var someObj = new SomeObj();
Method(someObj.someProperty); //Obtains the value of the property and passes it
Вызывающая сторона сделает это:
var someObj = new SomeObj();
Method(() => someObj.someProperty); //Passes an expression representing the property
Чтобы изменить Method
так, чтобы он мог работать таким образом, вам нужно немного разобрать выражения, но не намного:
static public bool Method<T>(Expression<Func<T>> expression) where T : class
{
var memberExp = (MemberExpression)expression.Body;
var propertyInfo = memberExp.Member as PropertyInfo;
var targetObject = Expression.Lambda<Func<object>>(memberExp.Expression).Compile()();
Console.WriteLine("Old value is {0}", propertyInfo.GetValue(targetObject));
if (someCondition1)
{
propertyInfo.SetValue(targetObject, null); //Set it to null
return false;
}
}
Если вы планируете вызывать это часто и вы беспокоитесь о производительности Compile()
, вы можете избежать компиляции с немного большим количеством кода:
static public bool Method<T>(Expression<Func<T>> expression)
{
var memberExp = (MemberExpression)expression.Body;
var propertyInfo = memberExp.Member as PropertyInfo;
var propertyExpression = memberExp.Expression as MemberExpression;
var targetObject = ((FieldInfo)propertyExpression.Member).GetValue((propertyExpression.Expression as ConstantExpression).Value);
Console.WriteLine("Old value is {0}", propertyInfo.GetValue(targetObject));
if (SomeCondition1)
{
propertyInfo.SetValue(targetObject, null);
return false;
}
}