如何重载功能一致但参数不同的扩展方法以避免代码重复?
避免扩展方法重复的几种实用方案
1. 抽离公共核心逻辑
把生成URL的核心代码单独拎出来写成通用方法,两个扩展方法只负责将各自类的参数传给这个核心方法,核心逻辑只需维护一处:
// 核心生成逻辑,仅需编写一次 private static string BuildEventUrl(string eventId, string eventType) { return $"/events/{eventType}/{eventId}"; } // SomeDataEventClass的扩展方法 public static string UrlHelper(this SomeDataEventClass e) { return BuildEventUrl(e.EventId, "some-event"); } // AnotherDataEventClass的扩展方法 public static string UrlHelper(this AnotherDataEventClass e) { return BuildEventUrl(e.EventId, "another-event"); }
这种方式改动最小,无需修改原有类的代码,适合快速复用逻辑。
2. 统一接口约束(最优解)
如果两个类具备生成URL所需的共同属性(比如都有EventId,且能提供事件类型标识),可以定义一个公共接口让它们实现,之后只需要写一个针对接口的扩展方法:
// 定义公共接口,约定生成URL需要的属性 public interface IEventData { string EventId { get; } string EventType { get; } } // 让两个类实现接口 public class SomeDataEventClass : IEventData { public string EventId { get; set; } public string EventType => "some-event"; // 其他原有属性... } public class AnotherDataEventClass : IEventData { public string EventId { get; set; } public string EventType => "another-event"; // 其他原有属性... } // 仅需一个扩展方法,所有实现IEventData的类都可复用 public static string UrlHelper(this IEventData e) { return $"/events/{e.EventType}/{e.EventId}"; }
这是最简洁的方案,后续新增同类事件类时,只要实现接口就能直接复用该扩展方法。
3. 泛型+反射(适配无法修改原有类的场景)
如果没办法修改SomeDataEventClass和AnotherDataEventClass的代码,也无法添加接口,可以用泛型配合反射来获取属性值:
public static string UrlHelper<T>(this T e, string eventType) { var eventIdProp = typeof(T).GetProperty("EventId"); if (eventIdProp == null) throw new InvalidOperationException($"类型 {typeof(T).Name} 缺少EventId属性"); var eventId = eventIdProp.GetValue(e)?.ToString(); return $"/events/{eventType}/{eventId}"; } // 调用示例 var someEventUrl = someEvent.UrlHelper("some-event"); var anotherEventUrl = anotherEvent.UrlHelper("another-event");
注意反射会带来一定性能损耗,非必要场景不推荐使用这种方式。
内容的提问来源于stack exchange,提问作者Amenawon Esezobor
相关产品推荐
相关产品推荐

