You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不修改自动生成类的前提下复用两个属性一致的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 17:20:58