(Zobacz poniżej rozwiązanie, które utworzyłem przy użyciu odpowiedzi, którą zaakceptowałem)
Usiłuję poprawić konserwowalność kodu wymagającego refleksji. Aplikacja ma interfejs zdalny .NET, odsłaniając (między innymi) metodę o nazwie Wykonaj, aby uzyskać dostęp do części aplikacji nie zawartych w opublikowanym zdalnym interfejsie.
Oto, w jaki sposób aplikacja określa właściwości (w tym przykładzie statyczne), które mają być dostępne za pośrednictwem polecenia Wykonaj:
RemoteMgr.ExposeProperty("SomeSecret", typeof(SomeClass), "SomeProperty");
Aby użytkownik zdalny mógł zadzwonić:
string response = remoteObject.Execute("SomeSecret");
a aplikacja użyłaby odbicia, aby znaleźć SomeClass.SomeProperty i zwrócić jego wartość jako ciąg.
Niestety, jeśli ktoś zmieni nazwę SomeProperty i zapomni zmienić trzecią parmę ExposeProperty (), zepsuje ten mechanizm.
Potrzebuję odpowiednika:
SomeClass.SomeProperty.GetTheNameOfThisPropertyAsAString()
do użycia jako 3. parma w ExposeProperty, aby narzędzia do refaktoryzacji zajęłyby się nazwami.
Czy jest na to sposób? Z góry dziękuję.
Okej, oto co ostatecznie stworzyłem (na podstawie wybranej przeze mnie odpowiedzi i pytania, do którego się odwołał):
// <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;
}
Stosowanie:
// Static Property
string name = GetPropertyName(() => SomeClass.SomeProperty);
// Instance Property
string name = GetPropertyName(() => someObject.SomeProperty);
Teraz dzięki tej fajnej funkcji czas uprościć metodę ExposeProperty. Polerowanie klamek to niebezpieczna praca ...
Dziękuję wszystkim.
źródło
Odpowiedzi:
Za pomocą GetMemberInfo stąd: Pobieranie nazwy właściwości z wyrażenia lambda możesz zrobić coś takiego:
RemoteMgr.ExposeProperty(() => SomeClass.SomeProperty)
źródło
GetMemberInfo
? Nic nie mogę znaleźć w pakiecie „wspólnych narzędzi” dla biblioteki Microsoft Enterprise Library, co sugeruje, że MSDN zawiera tę metodę. Istnieje pakiet „nieoficjalny”, ale bycie nieoficjalnym jest mało inspirujące. Odpowiedź JimC , która jest oparta na tej, jest znacznie bardziej zwięzła i nie opiera się na pozornie niedostępnej bibliotece.W wersji C # 6.0 nie jest to problem, ponieważ możesz:
To wyrażenie jest rozwiązywane w czasie kompilacji do
"SomeProperty"
.Dokumentacja MSDN nazwy nameof .
źródło
const string
! NiesamowiteRaiseProperty
w WPF! Użyj RaisePropertyChanged (nameof (właściwość)) zamiast RaisePropertyChanged („właściwość”)Istnieje dobrze znany hack do wyodrębnienia go z wyrażenia lambda (pochodzi z klasy PropertyObserver, autorstwa Josh Smith, w jego fundacji MVVM):
Przepraszamy, brakowało jakiegoś kontekstu. Była to część większej klasy, w której
TPropertySource
znajduje się klasa zawierająca właściwość. Możesz ustawić funkcję rodzajową w TPropertySource, aby wyodrębnić ją z klasy. Polecam zajrzeć do pełnego kodu z MVVM Foundation .źródło
public static string GetPropertyName<TPropertySource>(Expression<Func<TPropertySource, object>> expression)
a następnie wywołać tak:var name = GetPropertyName<TestClass>(x => x.Foo);
Okej, oto co ostatecznie stworzyłem (na podstawie wybranej przeze mnie odpowiedzi i pytania, do którego się odwołał):
Stosowanie:
źródło
PropertyInfo klasa powinna pomóc w osiągnięciu tego, czy dobrze rozumiem.
Metoda Type.GetProperties ()
Czy tego potrzebujesz?
źródło
Możesz użyć Odbicia, aby uzyskać rzeczywiste nazwy właściwości.
http://www.csharp-examples.net/reflection-property-names/
Jeśli potrzebujesz sposobu na przypisanie właściwości „String Name” do właściwości, dlaczego nie napiszesz atrybutu, nad którym możesz się zastanowić, aby uzyskać nazwę string?
źródło
Zmodyfikowałem twoje rozwiązanie, aby połączyć je w wiele właściwości:
Stosowanie:
źródło
Na podstawie odpowiedzi, która jest już zawarta w pytaniu oraz w tym artykule: https://handcraftsman.wordpress.com/2008/11/11/how-to-get-c-property-names-with-magic-strings/ I przedstawiam moje rozwiązanie tego problemu:
I Test, który pokazuje również użycie instancji i właściwości statycznych:
źródło
Stare pytanie, ale inną odpowiedzią na to pytanie jest utworzenie funkcji statycznej w klasie pomocniczej, która korzysta z CallerMemberNameAttribute.
A następnie użyj go w następujący sposób:
źródło
Możesz użyć klasy StackTrace, aby uzyskać nazwę bieżącej funkcji (lub jeśli umieścisz kod w funkcji, a następnie zejdź poziom niżej i uzyskaj funkcję wywołującą).
Zobacz http://msdn.microsoft.com/en-us/library/system.diagnostics.stacktrace(VS.71).aspx
źródło
Użyłem tej odpowiedzi z wielkim efektem: pobierz właściwość jako ciąg znaków z wyrażenia <Func <TModel, TProperty >>
Zdaję sobie sprawę, że już dawno odpowiedziałem na to pytanie. Jedyną zaletą mojej drugiej odpowiedzi jest to, że działa dla właściwości statycznych. Uważam, że składnia w tej odpowiedzi jest o wiele bardziej przydatna, ponieważ nie musisz tworzyć zmiennej typu, który chcesz odzwierciedlić.
źródło
Miałem pewne trudności z użyciem rozwiązań już sugerowanych dla mojego konkretnego przypadku użycia, ale w końcu to wymyśliłem. Nie sądzę, aby mój konkretny przypadek był wart nowego pytania, dlatego zamieszczam tutaj swoje rozwiązanie w celach informacyjnych. (Jest to bardzo ściśle związane z pytaniem i zapewnia rozwiązanie dla każdego, kto ma podobny przypadek do mojego).
Kod, na którym skończyłem, wygląda następująco:
Ważną częścią dla mnie jest to, że w
CompanyControl
klasie kompilator pozwoli mi tylko wybrać właściwość boolean,ICompanyViewModel
której ułatwienie innym programistom jest prawidłowe.Główną różnicą między moim rozwiązaniem a zaakceptowaną odpowiedzią jest to, że moja klasa jest ogólna i chcę dopasować właściwości tylko z typu ogólnego, które są boolowskie.
źródło
tak to zaimplementowałem. Powodem jest to, że jeśli klasa, która ma otrzymać nazwę od swojego członka, nie jest statyczna, musisz utworzyć instancję tego, a następnie uzyskać nazwę członka. więc ogólna pomoc przychodzi tutaj
użycie jest takie
źródło