复制非可空属性到可空属性时出现空值问题求助
解决非可空属性到可空属性的深拷贝问题
嘿,我完全懂你遇到的这个坑——把带有非可空属性的Child对象深拷贝到对应属性为可空的Parent对象时,结果居然得到了空值,这确实挺让人困惑的。咱们先拆解问题,再给你几个实用的解决方案:
首先先明确下典型的类结构(我猜你的场景大概是这样,如果不对可以调整):
// 带有非可空属性的Child类 public class Child { public string Name { get; set; } // 非可空字符串 public int Age { get; set; } // 非可空整数 } // 带有可空属性的Parent类 public class Parent { public string? Name { get; set; } // 可空字符串 public int? Age { get; set; } // 可空整数 }
方案1:手动实现深拷贝(最直接,可控性拉满)
其实在C#里,非可空类型的值可以安全赋值给对应的可空类型(比如string→string?、int→int?),所以手动映射根本不会有空值问题,除非你的Child对象本身属性没初始化(但非可空属性在严格nullable上下文里是必须初始化的)。
写个简单的深拷贝方法:
public static Parent DeepCopyChildToParent(Child child) { // 先判断源对象是否为空 if (child == null) return null; // 直接赋值非可空属性到可空属性 return new Parent { Name = child.Name, Age = child.Age }; } // 使用方式 var child = new Child { Name = "Alice", Age = 30 }; var parent = DeepCopyChildToParent(child); // 此时parent.Name和Age都会正确赋值,绝不会是空值
方案2:用AutoMapper处理复杂对象(减少重复代码)
如果你的对象有很多属性或者嵌套结构,手动写映射太麻烦,AutoMapper这类工具默认就支持非可空到可空的属性映射,只要属性名匹配就行:
首先配置映射规则:
var config = new MapperConfiguration(cfg => { // 直接创建Child到Parent的映射 cfg.CreateMap<Child, Parent>(); }); // 初始化映射器 var mapper = config.CreateMapper(); // 执行拷贝 var child = new Child { Name = "Bob", Age = 25 }; var parent = mapper.Map<Parent>(child); // 属性值会正确复制,没有空值问题
如果属性名不匹配,还可以手动指定映射关系:
cfg.CreateMap<Child, Parent>() .ForMember(dest => dest.ParentUserName, opt => opt.MapFrom(src => src.Name));
方案3:处理嵌套对象的深拷贝
如果你的Child和Parent包含嵌套的引用类型(比如地址类),需要实现真正的深拷贝(避免浅拷贝导致的引用共享问题):
// 嵌套的地址类 public class Address { public string Street { get; set; } public string City { get; set; } // 给地址类实现深拷贝方法 public Address DeepCopy() { return new Address { Street = this.Street, City = this.City }; } } // 更新后的Child和Parent类 public class Child { public string Name { get; set; } public int Age { get; set; } public Address Address { get; set; } } public class Parent { public string? Name { get; set; } public int? Age { get; set; } public Address? Address { get; set; } } // 带嵌套对象的深拷贝方法 public static Parent DeepCopyChildToParent(Child child) { if (child == null) return null; return new Parent { Name = child.Name, Age = child.Age, // 对嵌套对象也执行深拷贝 Address = child.Address?.DeepCopy() }; }
为啥你之前会得到空值?
大概率是因为你用了错误的拷贝方式——比如直接强制类型转换((Parent)child)但这不是拷贝,只是类型转换;或者用了某些序列化工具但配置有误,导致属性没被正确映射。用上面的方法就能彻底解决这个问题。
内容的提问来源于stack exchange,提问作者Balanjaneyulu K
相关产品推荐
相关产品推荐

