如何从C#基类Message初始化派生类TaggedMessage?
优雅实现Message到TaggedMessage的属性复制并添加标签
直接强制转换Message到TaggedMessage会失败,因为Message实例本身并非TaggedMessage类型——派生类实例包含基类没有的额外属性,基类实例无法自动升级为派生类实例。下面提供几种无需手动逐个赋值的优雅解决方案:
方案1:使用AutoMapper(推荐)
AutoMapper是.NET生态中成熟的对象映射库,能自动匹配同名同类型的属性完成赋值,后续Message属性变更时无需修改转换逻辑。
- 安装NuGet包:
dotnet add package AutoMapper - 配置映射(全局初始化一次即可):
var mapperConfig = new MapperConfiguration(cfg => { cfg.CreateMap<Message, TaggedMessage>(); }); IMapper mapper = mapperConfig.CreateMapper(); - 执行转换并添加标签:
Message originalMsg = new Message(); TaggedMessage taggedMsg = mapper.Map<TaggedMessage>(originalMsg); taggedMsg.MyTag = "Nature";
方案2:自定义反射工具类
如果不想引入第三方依赖,可以用反射实现通用的属性复制逻辑,遍历基类的公共属性并赋值给派生类实例:
public static class PropertyCopier { public static TTarget CopyProperties<TSource, TTarget>(TSource source, TTarget target) where TSource : class where TTarget : class { var sourceProps = typeof(TSource).GetProperties(BindingFlags.Public | BindingFlags.Instance); var targetProps = typeof(TTarget).GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var sourceProp in sourceProps) { var targetProp = targetProps.FirstOrDefault(p => p.Name == sourceProp.Name && p.PropertyType == sourceProp.PropertyType && p.CanWrite); targetProp?.SetValue(target, sourceProp.GetValue(source)); } return target; } } // 使用示例 Message originalMsg = new Message(); TaggedMessage taggedMsg = PropertyCopier.CopyProperties(originalMsg, new TaggedMessage()); taggedMsg.MyTag = "Nature";
方案3:在TaggedMessage中封装转换逻辑
把转换逻辑封装到派生类内部,对外提供简洁的调用接口,内部可以结合反射实现:
public class TaggedMessage : Message { public string MyTag { get; set; } // 接收Message的构造函数 public TaggedMessage(Message source) { // 用反射复制属性 var sourceProps = typeof(Message).GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var prop in sourceProps) { prop.SetValue(this, prop.GetValue(source)); } } // 静态工厂方法,直接生成带标签的实例 public static TaggedMessage FromMessage(Message source, string tag) { return new TaggedMessage(source) { MyTag = tag }; } } // 使用示例 Message originalMsg = new Message(); TaggedMessage taggedMsg = TaggedMessage.FromMessage(originalMsg, "Nature");
内容的提问来源于stack exchange,提问作者user2696330
相关产品推荐
相关产品推荐

