如何优雅修改集合中对象单个属性的数据类型(无需枚举所有属性)
优雅修改对象单个属性数据类型的实现方案
问题背景
需要修改对象特定属性的数据类型,但当前实现需枚举对象全部二十余个属性,仅为修改单个属性,操作繁琐。
现有实现
class Program { static void Main(string[] args) { NammaClass nammaClass = new NammaClass(); List<NammaClass> listNamma = new List<NammaClass> { new NammaClass{quant= 1, dattim = "01/01/2020"}, new NammaClass{quant= 2, dattim = "02/02/2022"} }; var newList = (from user in listNamma select new { quant = user.quant,// 不想手动写这行 dattim = DateTime.Parse(user.dattim) }).ToList(); } } public class NammaClass { public int quant; public string dattim; }
解决方案
方案1:目标DTO类 + AutoMapper自动映射(推荐,类型安全)
定义一个与原类结构一致但目标属性类型不同的DTO类:
public class NammaDto { public int quant; public DateTime dattim; }
使用AutoMapper自动映射所有同名同类型属性,仅配置需要转换的目标属性:
// 初始化映射配置 var mapperConfig = new MapperConfiguration(cfg => { cfg.CreateMap<NammaClass, NammaDto>() .ForMember(dest => dest.dattim, opt => opt.MapFrom(src => DateTime.Parse(src.dattim))); }); IMapper mapper = mapperConfig.CreateMapper(); // 执行列表转换 var newList = listNamma.Select(mapper.Map<NammaDto>).ToList();
AutoMapper会自动复制所有未配置的属性,无需手动枚举,兼顾类型安全与开发效率。
方案2:反射动态复制属性(无需新增类)
如果无法新增DTO类,可通过反射遍历原对象的字段/属性,复制所有值后仅修改目标属性:
var newList = listNamma.Select(item => { var expando = new ExpandoObject() as IDictionary<string, object>; // 遍历原类的所有字段(如果是属性则用GetProperties()) foreach (var field in typeof(NammaClass).GetFields()) { object value = field.GetValue(item); if (field.Name == "dattim") { expando[field.Name] = DateTime.Parse(value.ToString()); } else { expando[field.Name] = value; } } return expando; }).ToList();
注意:反射方式会损失编译期类型检查,仅适合临时场景或属性频繁变动的情况。
方案3:C# 9+ 记录类型扩展(需调整原类结构)
若能将原类改为记录类型,可配合目标记录类实现简洁转换:
// 原记录类 public record NammaRecord(int quant, string dattim); // 目标记录类 public record NammaDtoRecord(int quant, DateTime dattim); // 转换逻辑 var newList = listNamma.Select(item => new NammaDtoRecord(item.quant, DateTime.Parse(item.dattim)) ).ToList();
记录类型的不可变性保证了数据安全,语法简洁,但需调整原类结构。
内容的提问来源于stack exchange,提问作者Vivek Shukla
相关产品推荐
相关产品推荐

