如何为来自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
相关产品推荐
相关产品推荐

