.NET Framework 4.7:如何实现仅保留原始属性的对象扩展方法?
实现对象属性筛选并序列化为JSON的扩展方法
针对你的需求,在.NET Framework 4.7中可以通过两种实用方式实现:
方式一:强类型直接构造匿名对象(性能最优)
因为你明确知道要保留的属性属于Order类,直接针对该类型构造包含目标属性的匿名对象,这种方式无需反射,性能最好且类型安全:
public static class Extensions { public static string RemovePrimitives(this Order order) { // 构造仅包含需要属性的匿名对象 var logObject = new { order.FirstName, order.LastName, order.Age }; // 序列化为格式化后的JSON返回 return JsonConvert.SerializeObject(logObject, Formatting.Indented); } }
调用方式完全符合你的期望:
var order = new Order(); var forLog = order.RemovePrimitives();
方式二:通用反射实现(支持任意类型)
如果需要让扩展方法适配更多类型,而非仅Order,可以用反射动态提取指定属性:
public static class Extensions { // 通过参数传入要保留的属性名,灵活适配不同对象类型 public static string RemovePrimitives(this object obj, params string[] keepProperties) { if (obj == null) throw new ArgumentNullException(nameof(obj)); if (keepProperties == null || keepProperties.Length == 0) throw new ArgumentException("至少需要指定一个要保留的属性名", nameof(keepProperties)); var logObject = new ExpandoObject() as IDictionary<string, object>; var type = obj.GetType(); foreach (var propName in keepProperties) { var property = type.GetProperty(propName); if (property != null) { logObject[propName] = property.GetValue(obj); } } return JsonConvert.SerializeObject(logObject, Formatting.Indented); } }
调用时需指定要保留的属性:
var order = new Order(); var forLog = order.RemovePrimitives("FirstName", "LastName", "Age");
注意事项
- 确保项目已安装Newtonsoft.Json包(
JsonConvert来自该库),可通过NuGet包管理器完成安装。 - 使用反射方式时,需保证传入的属性名与类定义的属性名大小写完全一致(C#属性默认是PascalCase格式)。
- 两种方式序列化后的JSON都会保留原属性名,满足日志记录的格式需求。
内容的提问来源于stack exchange,提问作者TheBoubou
相关产品推荐
相关产品推荐

