C#存储第三方不同子类并统一访问公共属性name的方法
解决子类统一获取name属性的问题
针对你遇到的第三方库子类无法修改、但需要统一获取name属性的问题,有以下几种可行方案:
方案1:反射(无需修改现有结构,适配所有含name字段的子类)
利用反射直接读取实例的name字段,无需提前判断子类类型,新增子类时也不用修改代码:
foreach (ParentClass pc in dict.Values) { // 获取name字段的值,处理字段不存在的情况 string name = pc.GetType().GetField("name")?.GetValue(pc) as string; // 使用name }
优缺点:无需改动现有代码,自动适配所有带public string name字段的子类;但反射性能略低,且依赖字段名硬编码,若第三方库修改字段名会失效。
方案2:扩展方法+模式匹配(类型安全,需维护子类判断逻辑)
写一个针对ParentClass的扩展方法,用模式匹配统一处理子类的name获取,后续新增子类时只需在扩展方法里加对应分支:
public static class ParentClassExtensions { public static string GetName(this ParentClass pc) { return pc switch { ChildA ca => ca.name, ChildB cb => cb.name, // 新增子类时在这里加对应的分支 _ => null // 处理未匹配的情况 }; } } // 遍历使用 foreach (ParentClass pc in dict.Values) { string name = pc.GetName(); // 使用name }
优缺点:类型安全、性能好;但新增子类时需要手动更新扩展方法,适合子类数量不多或新增频率低的场景。
方案3:适配器模式(类型安全,扩展性强)
为每个子类创建适配器类,实现统一的INamed接口,将子类的name属性映射到接口的属性上:
// 定义统一接口 public interface INamed { string Name { get; } } // ChildA的适配器 public class ChildAAdapter : INamed { private readonly ChildA _child; public ChildAAdapter(ChildA child) => _child = child; public string Name => _child.name; } // ChildB的适配器 public class ChildBAdapter : INamed { private readonly ChildB _child; public ChildBAdapter(ChildB child) => _child = child; public string Name => _child.name; } // 遍历使用 foreach (ParentClass pc in dict.Values) { string name = pc switch { ChildA ca => new ChildAAdapter(ca).Name, ChildB cb => new ChildBAdapter(cb).Name, _ => null }; // 使用name }
优缺点:完全类型安全,扩展性好,新增子类只需新增对应适配器;但需要编写额外的适配器类,代码量略大。
内容的提问来源于stack exchange,提问作者CrayonApe
相关产品推荐
相关产品推荐

