Given this class:
public class MyClass
{
public int MyProperty {get; set;}
}
How will I be able to extract the name of MyProperty
in code?
For example, I am able to get the name of the class like this
typeof(MyClass).Name
How can I do something similar for the property?
The reason for the question is that I want this particular code to be resistant against refactorizations of the names.
EDIT: With resistant I mean that I want the code at the call site to be robust in the face of changes of the propertyname. I have some stuff that is using a string representation of the property name. Sorry for the poor phrasing. I did not include call site code in order to keep the problem clean and not wander off into other discussions on the nature of the call site code.
To get names of properties for a specific type use method Type. GetProperties. Method returns array of PropertyInfo objects and the property names are available through PropertyInfo.Name property.
public class myClass { public int a { get; set; } public int b { get; set; } public int c { get; set; } } public void myMethod(myClass data) { Dictionary<string, string> myDict = new Dictionary<string, string>(); Type t = data. GetType(); foreach (PropertyInfo pi in t. GetProperties()) { myDict[pi.Name] = //...
A property is a member that provides a flexible mechanism to read, write, or compute the value of a private field. Properties can be used as if they're public data members, but they're special methods called accessors.
Usage: // Static Property string name = GetPropertyName(() => SomeClass. SomeProperty); // Instance Property string name = GetPropertyName(() => someObject. SomeProperty);
You do it like this, using compiler generated expression trees:
public static string GetMemberName<T, TValue>(Expression<Func<T, TValue>> memberAccess)
{
return ((MemberExpression)memberAccess.Body).Member.Name;
}
Now call the static method from code:
class MyClass
{
public int Field;
public string Property { get; set; }
}
var fieldName = GetMemberName((MyClass c) => c.Field);
var propertyName = GetMemberName((MyClass c) => c.Property);
// fieldName has string value of `Field`
// propertyName has string value of `Property`
You can now also use refactoring to rename that field without breaking this code
In C# 6 we can do it very simply
nameof(MyField);
you can get method\type\propery\field\class\namespace names in the same way ex
nameof(MyClass);
nameof(namespacename1) // returns "namespacename1"
nameof(TestEnum.FirstValue) // returns enum's first value
MSDN Reference
Look at this post
With C# 6.0, you can use the new nameof
operator.
nameof(MyClass.MyField) // returns "MyField"
nameof(MyClass) //returns "MyClass"
See nameof (C# and Visual Basic Reference) for more examples.
Using Reflection you can find all Members from MyClass
with this.
MemberInfo[] members = typeof(MyClass).GetMembers();
Now you can find your desired property for each Member.
foreach ( MemberInfo memberInfo in members)
{
Console.WriteLine("Name: {0}", memberInfo.Name); // Name: MyField
Console.WriteLine("Member Type: {0}", memberInfo.MemberType); // Member Type: Property
}
If you want to find only Properties use PropertyInfo
instead of MemberInfo
.
Or write this
foreach ( MemberInfo memberInfo in members.Where(p => p.MemberType == MemberTypes.Property))
{
Console.WriteLine("Name: {0}", memberInfo.Name); // Name: MyField
Console.WriteLine("Member Type: {0}", memberInfo.MemberType); // Member Type: Property
}
You could use the following class which contains a method using an expression tree as an argument to determine a member name based on a lambda expression:
public class MemberHelper<T>
{
public string GetName<U>(Expression<Func<T, U>> expression)
{
MemberExpression memberExpression = expression.Body as MemberExpression;
if (memberExpression != null)
return memberExpression.Member.Name;
throw new InvalidOperationException("Member expression expected");
}
}
Then use it like so:
MemberHelper<MyClass> memberHelper = new MemberHelper<MyClass>();
string name = memberHelper.GetName(x => x.MyField);
If you only want to get name of an instance member, you can use shorter code:
public static string GetMemberName<TValue>(Expression<Func<TValue>> memberAccess)
{
return ((MemberExpression)memberAccess.Body).Member.Name;
}
And use it like the following inside the class:
ReflectionTools.GetMemberName(() => _someInstanceVariableOrProperty)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With