如何在不修改自动生成类的前提下复用两个属性一致的C#类?
解决方案
问题场景
有两个自动生成、无法修改的同结构类:
namespace NP1 { public class AAA { public int A {get; set;} public int B {get; set;} } } namespace NP2 { public class AAA { public int A {get; set;} public int B {get; set;} } }
还有两个仅引用命名空间不同的助手类:
using NP1; public class N1Helper { // ...其他代码 var sth = new AAA(A: some_value, B: some_other_value); // ...其他代码 }
using NP2; public class N2Helper { // ...其他代码 var sth = new AAA(A: some_value, B: some_other_value); // ...其他代码 }
目标是将助手类逻辑合并为一份实现。
针对你的问题逐一解答
1. 使用泛型?
可以,但需要借助工厂委托绕过泛型无法直接约束构造函数/属性的限制。示例实现:
public class GenericHelper<T> where T : new() { private readonly Func<int, int, T> _instanceFactory; public GenericHelper(Func<int, int, T> factory) { _instanceFactory = factory; } public void Execute(int someValue, int someOtherValue) { var sth = _instanceFactory(someValue, someOtherValue); // 后续操作sth的属性,若要编译时检查属性存在,需结合接口包装(见下文) } } // 使用方式 var np1Helper = new GenericHelper<NP1.AAA>((a, b) => new NP1.AAA { A = a, B = b }); var np2Helper = new GenericHelper<NP2.AAA>((a, b) => new NP2.AAA { A = a, B = b });
2. 事后让NP1.AAA和NP2.AAA实现公共接口?
直接用分部类不行(要求同命名空间+同程序集,自动生成类通常不满足),但可以用适配器包装类间接实现接口约束:
先定义公共接口:
public interface IAAA { int A { get; set; } int B { get; set; } }
为每个AAA类写包装类:
public class NP1AAAWrapper : IAAA { private readonly NP1.AAA _innerObj; public NP1AAAWrapper(int a, int b) => _innerObj = new NP1.AAA { A = a, B = b }; public int A { get => _innerObj.A; set => _innerObj.A = value; } public int B { get => _innerObj.B; set => _innerObj.B = value; } } public class NP2AAAWrapper : IAAA { private readonly NP2.AAA _innerObj; public NP2AAAWrapper(int a, int b) => _innerObj = new NP2.AAA { A = a, B = b }; public int A { get => _innerObj.A; set => _innerObj.A = value; } public int B { get => _innerObj.B; set => _innerObj.B = value; } }
然后写统一的助手类:
public class AAAHelper { public void DoWork(IAAA aaa) { // 编译时安全操作A、B属性 } } // 使用方式 var helper = new AAAHelper(); helper.DoWork(new NP1AAAWrapper(some_value, some_other_value)); helper.DoWork(new NP2AAAWrapper(some_value, some_other_value));
3. 其他方法?
方法一:动态类型(Dynamic)
放弃编译时检查,直接用dynamic统一逻辑,代码最简洁但有运行时风险:
public class DynamicAAAHelper { public void DoWork<T>(int someValue, int someOtherValue) where T : new() { dynamic sth = new T(); sth.A = someValue; sth.B = someOtherValue; // 后续操作 } } // 使用方式 var helper = new DynamicAAAHelper(); helper.DoWork<NP1.AAA>(some_value, some_other_value); helper.DoWork<NP2.AAA>(some_value, some_other_value);
方法二:源代码生成器
如果自动生成类的结构固定,可以编写C#源代码生成器,自动生成包装类或统一助手逻辑,适合长期维护的场景。
方法三:映射工具(如AutoMapper)
若需在两个AAA类间转换或批量操作,可借助AutoMapper简化映射逻辑,但单纯创建实例的话,包装类或泛型方案更直接。
内容的提问来源于stack exchange,提问作者xavier
相关产品推荐
相关产品推荐

