.net define function that takes a lambda expression
I want to define a function like the MVC extension template function TextBoxFor
The interesting thing for that function is that I don't have to specify a TProperty type. How can I set that in my function definition.
My code look like:
public class Helper<TItem>
{
public string GetMemberName(Expression<Func<TItem, TProperty>> expression)
{
... returns TProperty.Name
}
}
The actual problem is that this does not compile ... because it cannot find the TProperty type.
The result I want is to define the class once with a type ... and then use the function GetMemberName to get the name of each member like in 开发者_如何学运维MVC
framework.
Helper<Employee> h = new Helper<Employee>();
string name = h.GetMemberName(e=>e.Name);
....
I don't want to be forced to specify the TProperty type when I write the code. Basically it can be any object.
Thanks,
Radu
This is what you need:
public class Helper<TItem>
{
public string GetMemberName<TProperty>(Expression<Func<TItem, TProperty>> expression)
{
return string.Empty; // I didn't implement it
}
}
Just append <TProperty>
to your method name to make it generic. And the type of TProperty
can be inferred from provided expression, so you needn't to specify its type when using, can be simply:
Helper<Employee> h = new Helper<Employee>();
h.GetMemberName( e=>e.Name); //if Employee has such a property
Following function returns any property's name that is passed to it using a lambda expression:
public static string Property<T>(Expression<Func<T>> e)
{
var member = (MemberExpression)e.Body;
return member.Member.Name;
}
You can use the ModelMetaData
class to extract information from the Expression
.
public string GetMemberName<TProperty>(Expression<Func<TItem, TProperty>> expression) {
var meta = ModelMetaData.FromLambdaExpression(expression, null);
return meta.PropertyName; // Or something else
}
I wrote this function once but i can't remember it exactly.
But first change the delegate signature to this Func<T, object>
, then for simple data types get the expression body and cast it to MemberExpression and get the name of first parameter
if the accessed member is a complex one you must cast the expression body to UnaryExpression the take the first parameter and cast it to MemberExpression and do what you did in first step.
Playing with QuickWatch when debugging the function could lead you to the solution. Worth to mention that reading the HtmlHelper's in MVC code could be helpful.
EDIT: Roughly remembered
The better approach is to write this function as Extension Method(with constraint on type where applicable if you want) so that providing Employee type is also not needed anymore, cause it's inferred from usage.
So your function is like that:
public static class Helper
{
public static string Item<TItem,TMember>(this TItem obj, Expression<Func<TItem, TMember>> expression)
{
if (expression.Body is MemberExpression)
{
return ((MemberExpression)(expression.Body)).Member.Name;
}
if(expression.Body is UnaryExpression)
{
return ((MemberExpression)((UnaryExpression)(expression.Body)).Operand).Member.Name;
}
throw new InvalidOperationException();
}
}
So your code will be much cleaner
Employee emp = new Employee();
emp.Item(o=>o.Name);
Hope to helps you
精彩评论