Atrybut [Display] dla wartości enuma w C#
Po dłuższej przerwie znowu mam dla Was typowo techniczny wpis, a właściwie krótki pro-tip.
Dzisiaj pokaże funkcję, którą używam do wyciągania nazwy wartości enuma, dla której dodałem atrybut Display. Jeśli zajmujesz się aplikacjami webowymi w ASP.NET to prawdopodobnie zdarza Ci się dosyć często korzystać z atrybutu [Display] dla pól, których wartości będą wyświetlane np. użytkownikowi na stronie. Dzięki temu można w jednym miejscu podać przyjazną nazwę, którą można pokazać i w razie konieczności szybko zmienić. Niekiedy też nasze dane zawierają również typ enum, którego wartość trzeba też czasami wyświetlić. W tym celu można by robić drabinki ifów, switche i inne tego typu konstrukcje jednak skoro można podawać nazwę dla pól to może by by po prostu dodać dla każdej wartości enuma atrybutu [Display]? Jak najbardziej taka możliwość istnieje i wtedy nasz enum może wyglądać tak:
public enum Test { [Display(Name = "Przyjazna nazwa 1") FirstValue, [Display(Name = "Przyjazna nazwa 2") SecondValue, [Display(Name = "Przyjazna nazwa 3") ThirdValue }
Dobra, tylko jak teraz mając wartość tego enuma wziąć tą „ładniejszą” nazwę? Wbudowanego mechanizmu niestety nie ma, ale można skorzystać z mechanizmu refleksji i napisać rozszerzenie dla typu Enum. Może od razu pokażę jak ono u mnie wygląda:
public static class EnumNameHelper { public static string GetEnumName(this Enum value) { var enumType = value.GetType(); var enumValue = Enum.GetName(enumType, value); var member = enumType.GetMember(enumValue)[0]; var attrs = member.GetCustomAttributes(typeof(DisplayAttribute), false); var outString = ((DisplayAttribute)attrs[0]).Name; return outString; } }
W skrócie tylko napiszę jak to działa. Po pierwsze utworzenie klasy statycznej i podanie jako parametru this Enum value pozwala używać naszej funkcji w następujący sposób:
var enumValue = Test.FirstValue; var name = enumValue.GetEnumName();
Zaś w samej funkcji: najpierw bierzemy konkretny typ naszej wartości, następnie bierzemy nazwę naszej wartości (nazwę czyli np. FirstValue mając jako przykład podany wcześniej enum), a mając nazwę wartości możemy wziąć składnik enuma, który właśnie tak się nazywa. Teraz już tylko wybieramy wszystkie przypisane do niego atrybuty typu DisplayAttribute, bierzemy pierwszy z nich i wyciągamy wpisaną nazwę. Jak pewnie niektórzy zauważyli problem może się pojawić kiedy żaden atrybut nie będzie dodany dla wartości, wtedy indeks wyjdzie poza zakres. Ale myślę, że każdy z Was potrafi dopisać stosowne zabezpieczenie ;) Ja po prostu założyłem, że wiem co robię i wywołuję funkcję tylko dla enumów mających opisy.
I to tyle. Mam nadzieję, że komuś tego typu funkcja się przyda i ułatwi życie :)
Czy mógł byś opisać jak to zrobić dla ComboBox-a w WPF?