C#中父类ParentClass实例转ChildClass为null,如何附加额外字段?
转型失败原因
C# 中的引用类型类型转换只修改引用的类型标记,不会改变堆上实例本身的实际类型。向下转型(父类引用转为子类引用)成功的唯一前提是该引用指向的实例本身就是子类类型。
你代码中c1指向的是通过new ParentClass()创建的父类实例,它的底层类型标识就是ParentClass,也没有预留field3对应的内存空间,自然无法通过as转为ChildClass类型,操作结果就会返回null。
实现附加字段的可行方案
方案1:组合封装自定义类
新增一个包装类同时持有原父类实例和附加字段,对原有逻辑侵入最低:public class ParentWithExtraField { public ParentClass OriginalInstance { get; set; } public string field3 { get; set; } } // 使用示例 var wrappedObj = new ParentWithExtraField { OriginalInstance = c1, field3 = "ccc" }; // 原有字段访问方式:wrappedObj.OriginalInstance.field1方案2:创建子类实例拷贝父类属性
如果需要转型后的对象仍然兼容ParentClass的使用场景,可以新建子类实例,把原父类的字段值全部拷贝过去,可给ChildClass新增接收父类实例的构造函数简化拷贝逻辑:public class ChildClass : ParentClass { public ChildClass(ParentClass parent) { field1 = parent.field1; field2 = parent.field2; } public string field3; } // 使用示例 var c2 = new ChildClass(c1) { field3 = "ccc" };如果父类字段较多,也可以用反射、AutoMapper等工具简化拷贝代码。
方案3:动态附加扩展数据
如果你不想新增类,也不想修改原有实例的类型,可以用ConditionalWeakTable给实例动态挂载附加数据,不会影响原实例的GC回收:public static class ParentClassExtensions { private static readonly ConditionalWeakTable<ParentClass, string> _extraFields = new(); public static void SetField3(this ParentClass instance, string value) { _extraFields.AddOrUpdate(instance, value); } public static string GetField3(this ParentClass instance) { _extraFields.TryGetValue(instance, out var value); return value; } } // 使用示例 c1.SetField3("ccc"); var field3Value = c1.GetField3();
内容的提问来源于stack exchange,提问作者Bob5421
相关产品推荐
相关产品推荐

