如何在Type字典中匹配可空枚举的typeof类型?
反射格式化对象属性时的可空枚举匹配问题
我正在使用反射来确定如何格式化对象的属性。以下是一个formatters字典:
var formatters = new Dictionary<Type, Func<object, object>>() { { typeof(Enum), x => ((Enum)x)?.FormatEnum() }, { typeof(DateTime?), x => ((DateTime?)x)?.ToShortDateString() }, { typeof(string), x => x.ToString().ToLower() } };
大多数类型都能正常工作,但当获取可空枚举TaskStatus的类型时,它的类型不是Enum,而是该枚举自身的名称。我注意到它的基类型是Enum,但不想通过检查基类型来匹配,因为其他大多数类型直接用类型就能匹配成功。
例如,string类型的检查正常:
typeof(string).FullName = "System.String"
但对于TaskStatus枚举:
typeof(Enums.TaskStatus).FullName = "Enums.TaskStatus"
因此typeof(Enum) != typeof(Enums.TaskStatus),导致字典无法找到匹配项。
有没有办法不用添加所有使用的可空枚举类型名称,就能在formatters字典中找到匹配项?
补充完整代码
public class NoteHistory { [JsonProperty("Status")] public TaskStatus? TaskStatus { get; set; } [JsonProperty("CreatedDate")] public DateTime? CreatedDate { get; set; } [JsonProperty("Description")] public string Description { get; set; } public bool IsDeleted { get; set; } // not interested in comparing this } public enum TaskStatus { ToDo, Done } public static void DisplayValues() { var noteHistory1 = new NoteHistory { TaskStatus = TaskStatus.ToDo }; var noteHistory2 = new NoteHistory { TaskStatus = TaskStatus.Done }; // Get all properties with JsonProperty attr. var propertiesToCompare = typeof(NoteHistory) .GetProperties() .Where(x => x.CustomAttributes .Any(y => y.AttributeType.Name == nameof(JsonPropertyAttribute))); var comparers = new Dictionary<Type, Func<object, object, bool>> { { typeof(string), (x, y) => !string.Equals(x?.ToString(), y?.ToString(), StringComparison.InvariantCultureIgnoreCase) } }; var formatters = new Dictionary<Type, Func<object, object>>() { { typeof(Enum), x => ((Enum)x)?.FormatEnum() }, // doesn't work { typeof(DateTime?), x => ((DateTime?)x)?.ToShortDateString() }, { typeof(string), x => x.ToString().ToLower() }, }; foreach (var propertyToCompare in propertiesToCompare) { var prop1Value = propertyToCompare.GetValue(noteHistory1); var prop2Value = propertyToCompare.GetValue(noteHistory2); Func<object, object, bool> comparer; comparers.TryGetValue(propertyToCompare.PropertyType, out comparer); var hasChanged = comparer?.Invoke(prop1Value, prop2Value) ?? prop1Value != prop2Value; if (hasChanged) { Func<object, object> formatter; formatters.TryGetValue(propertyToCompare.PropertyType, out formatter); var formattedValue = formatter?.Invoke(noteHistory2); // TODO: display the value } } }
内容的提问来源于stack exchange,提问作者David Klempfner
相关产品推荐
相关产品推荐

