C# How To Pass A Property As A Variable

Do you like this?

Summary:
This post shows you how to pass a property as a variable in C#.


Content:

Let's suppose a scenario from which we can understand what we want to achieve and how it can be done. Assume we want to build a method which can connect to the database server and return a single record which satisfies our criteria. We can make it as simple as this database.find(string selectStatement). However, we can end up writing hard code as follows:

  • database.find("select * from TABLE1 where COLUMN1_1='VALUE'")
  • database.find("select * from TABLE2 where COLUMN1_2='VALUE'")
  • database.find("select * from TABLE3 where COLUMN1_3='VALUE'")
You can also elaborate more on this like:
  • database.find("TABLE1", "COLUMN1_1", "VALUE")
  • database.find("TABLE2", "COLUMN1_2", "VALUE")
  • database.find("TABLE3", "COLUMN1_3", "VALUE")
With that, you are still hard coding though. What if you have to change the table's name? Then you have to change the corresponding model class' name? You might also want to change the column's name.

What we are trying to achieve here is having a method which can take properties as input. Then we can use some sort of a reflection method to determine the name of the properties and its parent class' name. However, you can't do like below:
  • database.find(table1Instance.column1_1)
  • database.find(table2Instance.column1_2)
  • database.find(table3Instance.column1_3)
The reason is that you would only receive the values of the properties. What you can do is using Expression Tree in C# as below:
  • database.find(() => table1Instance.column1_1)
  • database.find(() => table2Instance.column1_2)
  • database.find(() => table3Instance.column1_3)
What () => table1Instance.column1_1 does is creating a lambda function of the type System.Func<TResult> which returns a result and takes no arguments as parameters. The signature of the method database.find() should be:
public object find(Expression<Func<object>> expression){

	PropertyInfo propertyInfo;

	if (expression.Body is UnaryExpression)
	{
		propertyInfo = ((MemberExpression)((UnaryExpression)expression.Body).Operand).Member as PropertyInfo;
	}
	else {
		propertyInfo = ((MemberExpression)expression.Body).Member as PropertyInfo;
	}

	

	if (propertyInfo == null)
	{
		throw new ArgumentException("The lambda expression 'property' should point to a valid Property");
	}

	string parentClassName = ((MemberInfo)propertyInfo).DeclaringType.Name;
	string propertyName = propertyInfo.Name;
	object propertyValue= expression.Compile()();
	string propertyType= propertyInfo.GetMethod.ReturnType.Name; //string, int, double
	
	//You can do the rest here:
	//string.Format("Select * from {0} where {1} = \"{2}\"", parentClassName, propertyName, propertyValue)
}

 
comments powered by Disqus