如何泛化签名几乎相同的C#方法?
重构重复的UISchemaBuilder添加方法
问题背景
目前有一组UISchemaBuilder的添加方法,每个方法签名高度相似,都接收一个继承自UISchemaParameters的参数类,最终都调用同一个私有Add方法:
public UISchemaBuilder AddText(UISchemaTextParameters parameters) => Add(parameters); public UISchemaBuilder AddTextLine(UISchemaTextLineParameters parameters) => Add(parameters); public UISchemaBuilder AddTextArea(UISchemaTextAreaParameters parameters) => Add(parameters); // 更多类似方法...
私有Add方法实现如下:
private UISchemaBuilder Add(UISchemaParameters parameters) { CreateUISchemaItem( parameters.Name, parameters.Title, parameters.IsRequired, parameters.IsReadOnly, parameters.IsMultiple, parameters.UIControlGet()); return this; }
所有参数类均继承自抽象类UISchemaParameters:
public abstract class UISchemaParameters { protected UISchemaParameters() { } protected UISchemaParameters(NameLocalizedTitle nameTitle) { Name = nameTitle.Name; Title = nameTitle.Title; } public string Name { get; set; } public string Title { get; set; } public bool? IsReadOnly { get; set; } public bool? IsRequired { get; set; } public bool? IsMultiple { get; set; } public abstract UIControlAttribute UIControlGet(); }
示例参数类(如UISchemaTextAreaParameters):
public class UISchemaTextAreaParameters : UISchemaParameters { public UISchemaTextAreaParameters() {} public UISchemaTextAreaParameters(NameLocalizedTitle nameTitle) : base(nameTitle) { } public uint? MaxLength {get;set;} public override UIControlAttribute UIControlGet() => new UIControlStringAttribute() { Parameters = new UISchemaStringFieldParameters { MaxLength = MaxLength }, IsMultiple = true }; }
现在需要重构这些重复的AddXXX方法,消除代码冗余。
重构方案
方案1:用泛型方法替代多个重载
直接提供一个泛型版的Add方法,约束泛型参数必须继承自UISchemaParameters,这样就能一次性替代所有AddXXX方法:
public UISchemaBuilder Add<TParameters>(TParameters parameters) where TParameters : UISchemaParameters { return Add(parameters); // 直接复用原私有Add方法逻辑 }
调用时编译器会自动推断泛型类型,写法简洁且保留类型安全:
builder.Add(new UISchemaTextParameters { Name = "username", Title = "用户名" }); builder.Add(new UISchemaTextAreaParameters { Name = "desc", Title = "描述", MaxLength = 500 });
如果想保留AddText这类语义化命名方法来提升可读性,只需保留简单的包装即可,无需重复逻辑:
public UISchemaBuilder AddText(UISchemaTextParameters parameters) => Add(parameters); public UISchemaBuilder AddTextArea(UISchemaTextAreaParameters parameters) => Add(parameters); // 其余方法同理,仅做类型转发
方案2:静态工厂简化参数创建(可选)
如果参数初始化步骤较多,可以给每个参数类添加静态工厂方法,减少手动创建对象的代码:
public class UISchemaTextAreaParameters : UISchemaParameters { // 原有构造函数... public static UISchemaTextAreaParameters Create(string name, string title, uint? maxLength = null) { return new UISchemaTextAreaParameters { Name = name, Title = title, MaxLength = maxLength }; } }
调用时可以直接用工厂方法生成参数:
builder.Add(UISchemaTextAreaParameters.Create("desc", "描述", 500));
方案3:委托配置的泛型方法(进阶)
如果希望参数配置更连贯,可以提供一个带委托的泛型方法,直接在方法内创建并配置参数:
public UISchemaBuilder Add<TParameters>(Action<TParameters> configure) where TParameters : UISchemaParameters, new() { var parameters = new TParameters(); configure(parameters); return Add(parameters); }
调用时无需手动实例化参数,直接通过委托配置属性:
builder.Add<UISchemaTextAreaParameters>(p => { p.Name = "desc"; p.Title = "描述"; p.MaxLength = 500; p.IsRequired = true; });
总结
最直接的重构方式是方案1的泛型方法,能彻底消除重复的AddXXX方法,同时保留类型安全。如果需要保留原有语义化方法名,可以保留简单的包装;如果想优化调用体验,可以结合方案2或方案3进一步简化参数创建流程。
内容的提问来源于stack exchange,提问作者Anthony
相关产品推荐
相关产品推荐

