在.NET C#中如何将动态对象转换为具体类型对象?
这其实是.NET里非常常见的匿名对象转强类型实例的场景,分两种属性匹配情况来处理,我给你详细拆解下可行的方案:
1. 属性名完全匹配的场景(转
Student类) 因为你的匿名对象{ Id = 1, Name = "Patrick" }的属性名和Student类的Id、Name完全对应,所以有几种简单的实现方式:
方法一:手动动态赋值
利用dynamic类型直接访问匿名对象的属性,手动赋值给Student实例,这是最直观的方式:
object obj = new { Id = 1, Name = "Patrick" }; var anonymousObj = obj as dynamic; Student student = new Student { Id = anonymousObj.Id, Name = anonymousObj.Name };
方法二:序列化反序列化中转
借助JSON序列化库(比如Newtonsoft.Json或System.Text.Json),先把匿名对象序列化成JSON字符串,再反序列化成目标类型:
// 用Newtonsoft.Json的示例 using Newtonsoft.Json; object obj = new { Id = 1, Name = "Patrick" }; string jsonStr = JsonConvert.SerializeObject(obj); Student student = JsonConvert.DeserializeObject<Student>(jsonStr); // 用System.Text.Json的示例 using System.Text.Json; Student student = JsonSerializer.Deserialize<Student>(JsonSerializer.Serialize(obj));
2. 属性名不匹配的场景(转
Scholar类) 这里匿名对象的Id对应Scholar的UniqueId,Name对应FullName,需要做属性映射,方案如下:
方法一:手动映射(简单场景首选)
同样用dynamic访问匿名对象属性,手动对应到目标类的属性:
object obj = new { Id = 1, Name = "Patrick" }; var anonymousObj = obj as dynamic; Scholar scholar = new Scholar { UniqueId = anonymousObj.Id, FullName = anonymousObj.Name };
方法二:反射实现通用映射工具
如果需要处理大量类似的映射场景,可以写一个通用的反射工具类,自定义属性匹配规则:
using System.Reflection; using System.Linq; public static class ObjectMapper { public static T MapTo<T>(object source) where T : new() { if (source == null) return default; T target = new T(); var sourceProps = source.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); var targetProps = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var sourceProp in sourceProps) { // 自定义属性映射规则:这里可以根据需求扩展 var targetProp = targetProps.FirstOrDefault(p => (sourceProp.Name == "Id" && p.Name == "UniqueId") || (sourceProp.Name == "Name" && p.Name == "FullName") || p.Name.Equals(sourceProp.Name, StringComparison.OrdinalIgnoreCase)); if (targetProp != null && targetProp.CanWrite) { var propValue = sourceProp.GetValue(source); targetProp.SetValue(target, propValue); } } return target; } } // 使用示例 Scholar scholar = ObjectMapper.MapTo<Scholar>(obj);
方法三:用AutoMapper实现优雅映射
如果项目本身已经在使用AutoMapper,或者需要处理复杂的映射逻辑,这是最省心的方案:
using AutoMapper; // 先配置映射规则 var mapperConfig = new MapperConfiguration(cfg => { cfg.CreateMap<dynamic, Scholar>() .ForMember(dest => dest.UniqueId, opt => opt.MapFrom(src => src.Id)) .ForMember(dest => dest.FullName, opt => opt.MapFrom(src => src.Name)); }); IMapper mapper = mapperConfig.CreateMapper(); // 执行转换 object obj = new { Id = 1, Name = "Patrick" }; Scholar scholar = mapper.Map<Scholar>(obj);
额外注意点
- 使用
dynamic时要注意,如果匿名对象的属性名拼写错误,运行时会抛出异常,编译期无法检测; - 反射方案虽然通用,但性能略低,适合小批量数据转换;
- AutoMapper在复杂项目中能节省大量手动映射的代码,还支持更多高级映射规则(比如类型转换、嵌套对象映射等)。
内容的提问来源于stack exchange,提问作者Androidmuster
相关产品推荐
相关产品推荐

