Этот код в основном делает это:
class Program
{
static void Main()
{
var propName = Nameof<SampleClass>.Property(e => e.Name);
Console.WriteLine(propName);
}
}
public class Nameof<T>
{
public static string Property<TProp>(Expression<Func<T, TProp>> expression)
{
var body = expression.Body as MemberExpression;
if(body == null)
throw new ArgumentException("'expression' should be a member expression");
return body.Member.Name;
}
}
(Конечно, это - 3,5 кода...)
В то время как reshefm и Jon Skeet показывают надлежащий способ сделать это использование выражения, должно стоить отметить, что существует более дешевый способ сделать это для имен методов:
Обертка делегат вокруг Вашего метода, получите MethodInfo, и Вы хороши для движения. Вот пример:
private void FuncPoo()
{
}
...
// Get the name of the function
string funcName = new Action(FuncPoo).Method.Name;
, К сожалению, это работает только на методы; это не работает на свойства, поскольку у Вас не может быть делегатов в методах получателя свойства или методах установщика. (Походит на глупое ограничение, IMO.)
Обходное решение должно использовать дерево выражений, и демонтировать то дерево выражений для нахождения соответствующего MemberInfo
. Существует немного больше детали и комментария в это примечание (хотя не код для выведения участника - это находится в другом ТАК вопрос где-нибудь, я верю).
, К сожалению, поскольку деревья выражений не существуют в.NET 2.0, нет действительно никакого эквивалента.
Одно решение избежать опечаток состоит в том, чтобы иметь ряд средств доступа, которые выбирают соответствующее PropertyInfo
для особого свойства и модульного теста их. Это было бы единственным местом, которое имело строку в нем. Это избежало бы дублирования и сделало бы рефакторинг легче, но это является немного драконовским.
Расширение к тому, что сделал reshefm, упростило использование оператора nameof(), а также дало имена методов, членов и методов класса:
/// <summary>
/// Provides the <see cref="nameof"/> extension method that works as a workarounds for a nameof() operator,
/// which should be added to C# sometime in the future.
/// </summary>
public static class NameOfHelper
{
/// <summary>
/// Returns a string represantaion of a property name (or a method name), which is given using a lambda expression.
/// </summary>
/// <typeparam name="T">The type of the <paramref name="obj"/> parameter.</typeparam>
/// <typeparam name="TProp">The type of the property (or the method's return type), which is used in the <paramref name="expression"/> parameter.</typeparam>
/// <param name="obj">An object, that has the property (or method), which its name is returned.</param>
/// <param name="expression">A Lambda expression of this pattern: x => x.Property <BR/>
/// Where the x is the <paramref name="obj"/> and the Property is the property symbol of x.<BR/>
/// (For a method, use: x => x.Method()</param>
/// <returns>A string that has the name of the given property (or method).</returns>
public static string nameof<T, TProp>(this T obj, Expression<Func<T, TProp>> expression)
{
MemberExpression memberExp = expression.Body as MemberExpression;
if (memberExp != null)
return memberExp.Member.Name;
MethodCallExpression methodExp = expression.Body as MethodCallExpression;
if (methodExp != null)
return methodExp.Method.Name;
throw new ArgumentException("'expression' should be a member expression or a method call expression.", "expression");
}
/// <summary>
/// Returns a string represantaion of a property name (or a method name), which is given using a lambda expression.
/// </summary>
/// <typeparam name="TProp">The type of the property (or the method's return type), which is used in the <paramref name="expression"/> parameter.</typeparam>
/// <param name="expression">A Lambda expression of this pattern: () => x.Property <BR/>
/// Where Property is the property symbol of x.<BR/>
/// (For a method, use: () => x.Method()</param>
/// <returns>A string that has the name of the given property (or method).</returns>
public static string nameof<TProp>(Expression<Func<TProp>> expression)
{
MemberExpression memberExp = expression.Body as MemberExpression;
if (memberExp != null)
return memberExp.Member.Name;
MethodCallExpression methodExp = expression.Body as MethodCallExpression;
if (methodExp != null)
return methodExp.Method.Name;
throw new ArgumentException("'expression' should be a member expression or a method call expression.", "expression");
}
}
Использовать его:
static class Program
{
static void Main()
{
string strObj = null;
Console.WriteLine(strObj.nameof(x => x.Length)); //gets the name of an object's property.
Console.WriteLine(strObj.nameof(x => x.GetType())); //gets the name of an object's method.
Console.WriteLine(NameOfHelper.nameof(() => string.Empty)); //gets the name of a class' property.
Console.WriteLine(NameOfHelper.nameof(() => string.Copy(""))); //gets the name of a class' method.
}
}