I have the following method:
public bool Method(object obj){
var objType = obj.GetType();
//do some reflection to get obj properties for some logic
...
if(someCondition) {
obj = null;
return false;
}
if(condition2){ return true;}
return false;
}
Method call:
var someObj = SomeObj();
Method(someObj.someProperty);
public class SomeObj : IEntity{
public SomeProperty someProperty {get;set;} //this needs to be set to null in some conditions
}
I would like to have a general method that takes in all types of Entity objects, that's why it's of "object" type. Then I would like to get its type, and go through all the properties to perform some logic. In the end, based on certain condition, I would like to set the object passed in to null. However, the problem is that the object passed in is always a property of some other Entity object, so I can't set it to ref. How do I get around this?
You aren't currently passing a property into Method
. You are passing the value of the property. The method has no idea what the original property is and therefore cannot set it to null.
To get around this, you can pass in an Expression
representing the property instead of the property's value. Then your method can parse the expression and do whatever is needed, including reading and setting the value.
So instead of doing this
var someObj = new SomeObj();
Method(someObj.someProperty); //Obtains the value of the property and passes it
The caller would do this:
var someObj = new SomeObj();
Method(() => someObj.someProperty); //Passes an expression representing the property
To modify Method
so that it can work this way, you have to do a little bit of expression parsing, but not much:
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;
}
}
If you plan to call this frequently and you're worried about the performance of Compile()
, you can avoid the compilation with slightly more code:
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;
}
}