Reputation: 4297
I have got this class:
class foo
{
int val;
public int Val
{
set{ val = values; },
set{ val = values; }
}
}
I need to pass the property name to a DataBinding:
String propertyName = "Val";
ctrl.DataBindings.Add(propertyName, object, dataMember, true, DataSourceUpdateMode.Never);
I want to do something like this:
propertyName = typeof(foo).methods.Val.toString();
Upvotes: 1
Views: 156
Reputation: 51330
If you can use C#6, you have the nameof
operator, which does just that.
string propertyName = nameof(foo.Val);
If you use C# 5, you can leverage expression trees:
public static string GetPropertyName<TParent>(Expression<Func<TParent, object>> prop)
{
var expr = prop.Body;
if (expr.NodeType == ExpressionType.Convert)
expr = ((UnaryExpression)expr).Operand;
if (expr.NodeType == ExpressionType.MemberAccess)
return ((MemberExpression)expr).Member.Name;
throw new ArgumentException("Invalid lambda", "prop");
}
Use this helper function like this (assuming it's in a ReflectionHelper
class):
string propertyName = ReflectionHelper.GetPropertyName<foo>(x => x.Val);
This way, you can safely use refactorings in your IDE.
Upvotes: 5
Reputation: 1500535
As of C# 6, you can use the nameof
operator:
ctrl.DataBindings.Add(nameof(foo.Val), /* other arguments as before */);
Before C# 6, there's no really simple way to do this at compile-time. One option, however, is to have unit tests which check that all your property names are actual properties (checking with reflection).
Also note that in C# 5 there's CallerMemberNameAttribute
which is useful for implementing INotifyPropertyChanged
- but isn't as useful for your case.
The approach of using expression trees works, but it feels somewhat clunky to me. Although far lower tech, simple string constants and a unit test feels a bit simpler.
Upvotes: 1
Reputation: 26268
Check out statically typed reflection with LINQ: http://blogs.clariusconsulting.net/kzu/statically-typed-reflection-with-linq/
You can do:
string propertyName = Reflect<foo>.GetProperty(x => x.Val).Name;
Upvotes: 0
Reputation: 4679
I don't know if you're using INotifyPropertyChanged but there's some articles on how to avoid using "magic strings" here which may be of use:
Implementing NotifyPropertyChanged without magic strings
typesafe NotifyPropertyChanged using linq expressions
Upvotes: 1
Reputation: 7944
If you are not using C# 6, you need to pass around an Expression<Func<T>>
.
You can then do this with that object (if you are passing a property):
private string GetPropertyName(Expression<Func<T>> propertyExpession)
{
//the cast will always succeed if properly used
MemberExpression memberExpression = (MemberExpression)propertyExpression.Body;
string propertyName = memberExpression.Member.Name;
return propertyName;
}
You would use this like:
var propName = GetPropertyName(() => this.Val);
Upvotes: 1