问题
So I use the following utility to get the name of a field/property from an instance of a class...
public static string FieldName<T>(Expression<Func<T>> Source)
{
return ((MemberExpression)Source.Body).Member.Name;
}
This allows me to do the following:
public class CoolCat
{
public string KaratePower;
}
public class Program
{
public static Main()
{
public CoolCat Jimmy = new CoolCat();
string JimmysKaratePowerField = FieldName(() => Jimmy.KaratePower);
}
}
This is great for serialization and other times when I need a string representation of the field name.
But now, I want to be able to get the field name WITHOUT having an instance of the class - for instance, if I am setting up a table and want to dynamically link the FieldNames of the columns to actual fields in a class (so refactorings, etc. will not break it).
Basically, I feel like I just don't quite get the syntax of how to accomplish this, but I imagine that it will look something like this:
public static string ClassFieldName<T>(Func<T> PropertyFunction)
{
// Do something to get the field name? I'm not sure whether 'Func' is the right thing here - but I would imagine that it is something where I could pass in a lambda type expression or something of the sort?
}
public class Program
{
public static Main()
{
string CatsPowerFieldName = ClassFieldName<CoolCat>((x) => x.KaratePower);
// This 'CatsPowerFieldName' would be set to "KaratePower".
}
}
I hope that makes sense - I'm not very good with the vocab around this subject so I know that the question is a little vague.
回答1:
I have two methods I use to do this.
The first is an extension method that can be used on any object.
public static string GetPropertyName<TEntity, TProperty>(this TEntity entity, Expression<Func<TEntity, TProperty>> propertyExpression)
{
return propertyExpression.PropertyName();
}
Which is used like
public CoolCat Jimmy = new CoolCat();
string JimmysKaratePowerField = Jimmy.GetPropertyName(j => j.KaratePower);
The second I use when I don't have an object.
public static string PropertyName<T>(this Expression<Func<T, object>> propertyExpression)
{
MemberExpression mbody = propertyExpression.Body as MemberExpression;
if (mbody == null)
{
//This will handle Nullable<T> properties.
UnaryExpression ubody = propertyExpression.Body as UnaryExpression;
if (ubody != null)
{
mbody = ubody.Operand as MemberExpression;
}
if (mbody == null)
{
throw new ArgumentException("Expression is not a MemberExpression", "propertyExpression");
}
}
return mbody.Member.Name;
}
This can be used like so
string KaratePowerField = Extensions.PropertyName<CoolCat>(j => j.KaratePower);
回答2:
What you're trying to do is one of the reasons Microsoft created System.Reflection Try this:
using System.Reflection; // reflection namespace
public static List<Type> GetClassPropertyNames(Type myClass)
{
PropertyInfo[] propertyInfos;
propertyInfos = myClass.GetProperties(BindingFlags.Public);
List<Type> propertyTypeNames = new List<Type>();
// write property names
foreach (PropertyInfo propertyInfo in propertyInfos)
{
propertyTypeNames .Add(propertyInfo.PropertyType);
}
return propertyNames;
}
回答3:
I believe using Reflection will be useful here. I do not have VS with me right now, but I'm sure you can do something like typeof(class).GetMembers(). My reflection is a little rusty.
来源:https://stackoverflow.com/questions/10899071/get-the-name-of-a-field-from-a-class-without-an-instance