(См. Ниже решение, которое я создал, используя ответ, который я принял)
Я пытаюсь улучшить удобство сопровождения некоторого кода с помощью отражения. Приложение имеет интерфейс .NET Remoting, который предоставляет (помимо прочего) метод Execute для доступа к частям приложения, не включенным в опубликованный удаленный интерфейс.
Вот как приложение определяет свойства (статические в этом примере), которые должны быть доступны через Execute:
RemoteMgr.ExposeProperty("SomeSecret", typeof(SomeClass), "SomeProperty");
Таким образом, удаленный пользователь может позвонить:
string response = remoteObject.Execute("SomeSecret");
и приложение будет использовать отражение, чтобы найти SomeClass.SomeProperty и вернуть его значение в виде строки.
К сожалению, если кто-то переименует SomeProperty и забудет изменить третий параметр ExposeProperty (), это нарушит этот механизм.
Мне нужно эквивалент:
SomeClass.SomeProperty.GetTheNameOfThisPropertyAsAString()
использовать в качестве третьего параметра в 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. Полировка дверных ручек - опасная работа ...
Спасибо всем.
источник
Ответы:
Используя GetMemberInfo отсюда: получая имя свойства из лямбда-выражения, вы можете сделать что-то вроде этого:
RemoteMgr.ExposeProperty(() => SomeClass.SomeProperty)
источник
GetMemberInfo
? Я не могу найти ничего с пакетом «общих утилит» для Microsoft Enterprise Library, который, как кажется, указывает MSDN, содержит этот метод. Есть "неофициальный" пакет, но быть неофициальным - скучно. Ответ JimC , основанный на этом, гораздо более лаконичен и не зависит от, казалось бы, недоступной библиотеки.С C # 6.0 это теперь не проблема, как вы можете сделать:
Это выражение разрешается во время компиляции в
"SomeProperty"
.MSDN документация имени .
источник
const string
! УдивительноRaiseProperty
в WPF! Используйте RaisePropertyChanged (nameof (property)) вместо RaisePropertyChanged ("property")Есть известный хак для извлечения его из лямбда-выражения (это из класса PropertyObserver Джоша Смита в его фундаменте MVVM):
Извините, здесь не хватает контекста. Это было частью большего класса, где
TPropertySource
находится класс, содержащий свойство. Вы можете сделать функцию универсальной в TPropertySource, чтобы извлечь ее из класса. Я рекомендую взглянуть на полный код от MVVM Foundation .источник
public static string GetPropertyName<TPropertySource>(Expression<Func<TPropertySource, object>> expression)
затем вызвать так:var name = GetPropertyName<TestClass>(x => x.Foo);
Хорошо, вот что я в итоге создал (основываясь на выбранном мной ответе и вопросе, на который он ссылался):
Использование:
источник
Класс PropertyInfo должен помочь вам достичь этого, если я правильно понимаю.
Метод Type.GetProperties ()
Это то, что тебе надо?
источник
Вы можете использовать Reflection для получения фактических имен свойств.
http://www.csharp-examples.net/reflection-property-names/
Если вам нужен способ присвоения «Строкового имени» свойству, почему бы вам не написать атрибут, который вы можете отразить, чтобы получить строковое имя?
источник
Я изменил ваше решение, чтобы связать несколько свойств:
Использование:
источник
Основанный на ответе, который уже находится в вопросе и на этой статье: https://handcraftsman.wordpress.com/2008/11/11/how-to-get-c-property-names-without-magic-strings/ I представляю свое решение этой проблемы:
И тест, который также показывает использование например и статических свойств:
источник
Старый вопрос, но другой ответ на этот вопрос заключается в создании статической функции в классе помощника, который использует атрибут CallerMemberNameAttribute.
И затем используйте это как:
источник
Вы можете использовать класс StackTrace, чтобы получить имя текущей функции (или, если вы поместите код в функцию, затем уменьшите уровень и получите вызывающую функцию).
См. Http://msdn.microsoft.com/en-us/library/system.diagnostics.stacktrace(VS.71).aspx
источник
Я использовал этот ответ, чтобы получить отличный эффект: получить свойство в виде строки из выражения <Func <TModel, TProperty >>
Я понимаю, что уже ответил на этот вопрос некоторое время назад. Единственное преимущество, которое дает другой мой ответ - это то, что он работает для статических свойств. Я нахожу синтаксис в этом ответе гораздо более полезным, потому что вам не нужно создавать переменную того типа, который вы хотите отразить.
источник
У меня были некоторые трудности с использованием решений, уже предложенных для моего конкретного случая использования, но в конце концов я понял это. Я не думаю, что мой конкретный случай достоин нового вопроса, поэтому я публикую свое решение здесь для справки. (Это очень тесно связано с вопросом и предоставляет решение для всех, кто имеет аналогичный случай с моим).
Код, с которым я закончил, выглядит так:
Важной частью для меня является то, что в
CompanyControl
классе компилятор позволит мне только выбрать логическое свойствоICompanyViewModel
которое упрощает понимание другими разработчиками.Основное различие между моим решением и принятым ответом состоит в том, что мой класс является универсальным, и я хочу сопоставлять только свойства из универсального типа, которые являются логическими.
источник
это то, как я это реализовал, причина в том, что если класс, которому вы хотите получить имя от своего члена, не является статичным, тогда вам нужно создать его экземпляр, а затем получить имя члена. настолько общий здесь приходит на помощь
использование так
источник