Получите название свойства как строка

(См. ниже решения, я создал использование ответа, который я принял),

Я пытаюсь улучшить пригодность для обслуживания некоторого кода, включающего отражение. Приложение имеет интерфейс Remoting.NET, выставляющий (среди прочего) метод под названием, Выполняются для доступа к частям приложения, не включенного в его опубликованный удаленный интерфейс.

Вот то, как приложение определяет свойства (статический в этом примере), которые предназначены, чтобы быть доступными через, Выполнитесь:

RemoteMgr.ExposeProperty("SomeSecret", typeof(SomeClass), "SomeProperty");

Таким образом, удаленный пользователь мог звонить:

string response = remoteObject.Execute("SomeSecret");

и приложение использовало бы отражение для нахождения SomeClass. SomeProperty и возвращают его значение как строку.

К сожалению, если кто-то переименовывает SomeProperty и забывает изменять 3-й parm ExposeProperty (), он повреждает этот механизм.

Мне нужно к эквиваленту:

SomeClass.SomeProperty.GetTheNameOfThisPropertyAsAString()

для использования в качестве, 3-й parm в ExposeProperty, о котором заботились бы настолько осуществляющие рефакторинг инструменты, переименовывает.

Существует ли способ сделать это?Заранее спасибо.

Хорошо, вот то, что я закончил тем, что создал (основанный на ответе, который я выбрал и вопрос, на который он сослался):

// <summary>
// Get the name of a static or instance property from a property access lambda.
// </summary>
// <typeparam name="T">Type of the property</typeparam>
// <param name="propertyLambda">lambda expression of the form: '() => Class.Property' or '() => object.Property'</param>
// <returns>The name of the property</returns>
public string GetPropertyName<T>(Expression<Func<T>> propertyLambda)
{
    var me = propertyLambda.Body as MemberExpression;

    if (me == null)
    {
        throw new ArgumentException("You must pass a lambda of the form: '() => Class.Property' or '() => object.Property'");
    }

    return me.Member.Name;
 }

Использование:

// Static Property
string name = GetPropertyName(() => SomeClass.SomeProperty);

// Instance Property
string name = GetPropertyName(() => someObject.SomeProperty);

Теперь с этой прохладной возможностью, пора упростить метод ExposeProperty. Полировка ручек двери является опасной работой...

Спасибо все.

191
задан Jim C 12 May 2010 в 08:08
поделиться

5 ответов

Используя GetMemberInfo отсюда: Получив имя свойства из лямбда-выражения , вы можете сделать что-то вроде этого:

RemoteMgr.ExposeProperty (( ) => SomeClass.SomeProperty)

public class SomeClass
{
    public static string SomeProperty
    {
        get { return "Foo"; }
    }
}

public class RemoteMgr
{
    public static void ExposeProperty<T>(Expression<Func<T>> property)
    {
        var expression = GetMemberInfo(property);
        string path = string.Concat(expression.Member.DeclaringType.FullName,
            ".", expression.Member.Name);
        // Do ExposeProperty work here...
    }
}

public class Program
{
    public static void Main()
    {
        RemoteMgr.ExposeProperty("SomeSecret", () => SomeClass.SomeProperty);
    }
}
59
ответ дан 23 November 2019 в 05:32
поделиться

Вы можете использовать Reflection для получения фактических имен свойств.

http://www.csharp-examples.net/reflection-property-names/

Если вам нужен способ присвоить свойству "строковое имя", почему бы вам не написать атрибут, над которым вы можете отразить, чтобы получить строковое имя?

[StringName("MyStringName")]
private string MyProperty
{
    get { ... }
}
6
ответ дан 23 November 2019 в 05:32
поделиться

Класс PropertyInfo должен помочь вам в этом, если я правильно понимаю.

  1. Метод Type.GetProperties ()

     PropertyInfo [] propInfos = typeof (ReflectedType) .GetProperties (); 
    propInfos.ToList (). ForEach (p => 
    Console.WriteLine (string.Format ("Имя свойства: {0}", p.Name)); 
     

Это то, что вам нужно?

8
ответ дан 23 November 2019 в 05:32
поделиться

Вы можете использовать класс StackTrace для получения имени текущей функции (или, если вы поместите код в функцию, то спуститесь на уровень ниже и получите вызывающую функцию).

См. http://msdn.microsoft.com/en-us/library/system.diagnostics.stacktrace(VS.71).aspx

0
ответ дан 23 November 2019 в 05:32
поделиться

Есть известный хак для извлечения его из лямбда-выражения (это из класса PropertyObserver, Джош Смит, в его MVVM foundation):

    private static string GetPropertyName<TPropertySource>
        (Expression<Func<TPropertySource, object>> expression)
    {
        var lambda = expression as LambdaExpression;
        MemberExpression memberExpression;
        if (lambda.Body is UnaryExpression)
        {
            var unaryExpression = lambda.Body as UnaryExpression;
            memberExpression = unaryExpression.Operand as MemberExpression;
        }
        else
        {
            memberExpression = lambda.Body as MemberExpression;
        }

        Debug.Assert(memberExpression != null, 
           "Please provide a lambda expression like 'n => n.PropertyName'");

        if (memberExpression != null)
        {
            var propertyInfo = memberExpression.Member as PropertyInfo;

            return propertyInfo.Name;
        }

        return null;
    }

Извините, не хватает контекста. Это была часть более крупного класса, где TPropertySource - класс, содержащий свойство. Вы могли бы сделать функцию общей в TPropertySource, чтобы извлечь ее из класса. Я рекомендую взглянуть на полный код из MVVM Foundation.

17
ответ дан 23 November 2019 в 05:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: