sources/Google.Solutions.Settings/ComponentModel/EnumDisplayNameConverter.cs (76 lines of code) (raw):

// // Copyright 2024 Google LLC // // Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. // using Google.Solutions.Common.Util; using System; using System.ComponentModel; using System.Globalization; using System.Linq; using System.Reflection; namespace Google.Solutions.Settings.ComponentModel { /// <summary> /// Converts between enum member names and strings based on /// DisplayName attributes. /// </summary> public class EnumDisplayNameConverter : EnumConverter { public EnumDisplayNameConverter(Type type) : base(type) { Precondition.Expect(type.IsEnum, "Type must be an enum"); Precondition.Expect(type.GetFields().Any(), "Enum must have at least one member"); Precondition.Expect( !type .GetFields() .SelectMany(m => m.GetCustomAttributes<DescriptionAttribute>()) .Any() || type .GetFields() .SelectMany(m => m.GetCustomAttributes<DescriptionAttribute>()) .GroupBy(m => m.Description) .Max(g => g.Count()) == 1, "Type contains duplicate display names"); } public override bool CanConvertTo( ITypeDescriptorContext context, Type destinationType) { return destinationType == typeof(string); } public override object ConvertTo( ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { Precondition.ExpectNotNull(value, "value"); if (destinationType == typeof(string)) { // // Lookup attribute by member name. // var description = this.EnumType .GetField(value.ToString()) .GetCustomAttribute<DescriptionAttribute>()? .Description; return description ?? value.ToString(); } else { return base.ConvertTo(context, culture, value, destinationType); } } public override object ConvertFrom( ITypeDescriptorContext context, CultureInfo culture, object value) { Precondition.ExpectNotNull(value, "value"); // // Lookup member by attribute value. // var member = this.EnumType .GetFields() .Where(m => Equals( m.GetCustomAttribute<DescriptionAttribute>()?.Description, value)) .FirstOrDefault(); if (member != null) { // // We found the member that matches the description. // return Enum.Parse(this.EnumType, member.Name); } else { // // The member might not have a description attribute, // so try to parse directly. // return Enum.Parse(this.EnumType, value.ToString()); } } } }