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

如何为来自Nuget包的现有模型新增字段而无需创建新类?

前置注意事项

你待新增的属性中decimal Price和原InOrderItemModel类已有的Price属性重名,实现时需修改新增属性的命名(比如改为DiscountPrice、ExtraPrice等)避免冲突。

可行实现方案

方案1:C# 13+ 扩展属性(最简洁)

如果你使用的是C# 13及以上版本,直接用官方支持的扩展属性即可,无需修改原类,完全不影响现有逻辑:

public static class InOrderItemModelExtensions
{
    public static string OfferCode(this InOrderItemModel model) { get; set; }
    public static int ItemId(this InOrderItemModel model) { get; set; }
    public static decimal DiscountPrice(this InOrderItemModel model) { get; set; }
}

使用方式和原生属性完全一致:

var item = new InOrderItemModel();
item.OfferCode = "OFFER001";
// 原有属性读写不受任何影响
item.Description = "商品描述";

方案2:低版本C# 用ConditionalWeakTable实现附加属性

如果你的项目使用C# 12及更低版本,没有扩展属性支持,可以用ConditionalWeakTable存储附加属性,不会导致原对象内存泄漏:

public static class InOrderItemModelExtensions
{
    private static readonly ConditionalWeakTable<InOrderItemModel, AdditionalProps> _propStore = new();

    private sealed class AdditionalProps
    {
        public string OfferCode { get; set; }
        public int ItemId { get; set; }
        public decimal DiscountPrice { get; set; }
    }

    public static string GetOfferCode(this InOrderItemModel model)
        => _propStore.TryGetValue(model, out var props) ? props.OfferCode : default;
    public static void SetOfferCode(this InOrderItemModel model, string value)
        => _propStore.GetOrCreateValue(model).OfferCode = value;

    public static int GetItemId(this InOrderItemModel model)
        => _propStore.TryGetValue(model, out var props) ? props.ItemId : default;
    public static void SetItemId(this InOrderItemModel model, int value)
        => _propStore.GetOrCreateValue(model).ItemId = value;

    public static decimal GetDiscountPrice(this InOrderItemModel model)
        => _propStore.TryGetValue(model, out var props) ? props.DiscountPrice : default;
    public static void SetDiscountPrice(this InOrderItemModel model, decimal value)
        => _propStore.GetOrCreateValue(model).DiscountPrice = value;
}

使用方式:

var item = new InOrderItemModel();
item.SetOfferCode("OFFER001");
var code = item.GetOfferCode();

方案3:继承+隐式转换包装类(无需改现有传参逻辑)

如果原类没有被sealed密封,也可以用继承包装类实现,通过隐式转换兼容所有原有接收InOrderItemModel的逻辑:

public class ExtInOrderItemModel : InOrderItemModel
{
    public string OfferCode { get; set; }
    public int ItemId { get; set; }
    public decimal DiscountPrice { get; set; }

    public static implicit operator ExtInOrderItemModel(InOrderItemModel original)
    {
        return new ExtInOrderItemModel
        {
            Description = original.Description,
            Quantity = original.Quantity,
            Price = original.Price
        };
    }

    public static implicit operator InOrderItemModel(ExtInOrderItemModel extended)
    {
        return new InOrderItemModel
        {
            Description = extended.Description,
            Quantity = extended.Quantity,
            Price = extended.Price
        };
    }
}

使用方式:

ExtInOrderItemModel item = new InOrderItemModel { Description = "测试商品" };
item.OfferCode = "OFFER001";
// 原有接收InOrderItemModel的方法直接传参即可,无需手动转换
SubmitOrder(item);

补充说明

如果Nuget包中的原类标记了partial关键字,你也可以直接在项目中定义同名partial类补充新增属性,但绝大多数Nuget发布的类不会添加partial修饰,该方案可行性极低。

内容的提问来源于stack exchange,提问作者Arvind Chourasiya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 15:00:04