如何实现类似注解正则表达式One的可选参数方法?优化Reset方法
解决方案:C# 灵活参数传递的实现方式
针对你的三个问题,我逐一拆解并给出具体的实现方案:
1. 实现类似"注解式"接收参数的方法
你提到的类似正则表达式中One可接收参数的调用方式,在C#里最直接的实现是命名参数(Named Arguments) + **可选参数(Optional Parameters)的组合;如果想要更贴近"声明式注解"的灵活配置感,还可以用构建器模式(Builder Pattern)**来封装参数。
- 命名参数允许你在调用方法时通过参数名指定值,不用严格按参数顺序传递;
- 可选参数则为参数设置默认值,调用时可直接省略不需要的参数。
举个简单的示例:
// 定义带可选参数的方法 public static void Configure(bool enableLogging = false, int timeout = 30) { // 业务逻辑实现 } // 调用时用命名参数,类似"注解式"传参 Configure(timeout: 60); // 只传需要的参数,其他用默认值 Configure(enableLogging: true, timeout: 10); // 按需求指定参数
如果想要更像Attribute那样的链式配置体验,可以用构建器模式:
// 参数配置类 public class ResetOptions { public ShalvarType ShalvarType { get; set; } = 0; public DamanType DamanType { get; set; } = 0; // 其他枚举参数... } // 扩展方法实现链式配置 public static ResetOptions WithShalvarType(this ResetOptions options, ShalvarType type) { options.ShalvarType = type; return options; } // 调用写法 var options = new ResetOptions().WithShalvarType(ShalvarType.TypeA);
2. 图中方法的定义与实现(推测为灵活参数传递)
虽然看不到你附图的方法,但结合你的代码需求,这类方法大概率是命名参数+可选参数的实现,或是参数对象模式(把多个参数封装成一个类):
- 命名参数+可选参数:定义方法时给可选参数设置默认值,调用时通过参数名指定需要传递的参数,跳过不需要的;
- 参数对象模式:把所有可选参数封装到一个类中,方法只接收这个类的实例,调用时可以只设置需要的属性,灵活性拉满。
3. 改造你的Reset方法
针对你现有的Reset方法,我提供三种改造方案,让你可以灵活传递可选参数:
方案一:直接使用命名参数(最简单)
其实你当前的方法已经支持命名参数了!你可以直接在调用时指定参数名,跳过不需要的可选参数,比如:
// 只传递AstinType参数,其他可选参数用默认值 Reset(myPanel, formulaType.Astin, astinType: AstinType.MyType); // 只传递DamanType参数 Reset(myPanel, formulaType.Daman, damanType: DamanType.AnotherType);
不过这里有个小问题:当formulaType指定为某一类型时,其他类型的参数其实是无用的(比如指定formulaType.Shalvar时,damanType等参数不会被用到),这种情况下可以优化类型安全性。
方案二:参数对象+方法重载(更安全优雅)
我们可以把参数封装为抽象基类,然后为每种formulaType实现对应的参数类,再通过方法重载确保类型安全:
// 抽象参数基类 public abstract class ResetParameters { } // 对应Shalvar的参数类 public class ShalvarResetParameters : ResetParameters { public ShalvarType ShalvarType { get; set; } = 0; } // 对应Daman的参数类 public class DamanResetParameters : ResetParameters { public DamanType DamanType { get; set; } = 0; } // 其他类型的参数类同理... // 改造后的Reset方法,通过重载实现类型安全 public static void Reset(Panel panel, ShalvarResetParameters parameters) { var collection = shalvarFurmula(parameters.ShalvarType); UpdateControls(panel, collection); } public static void Reset(Panel panel, DamanResetParameters parameters) { var collection = damanFurmula(parameters.DamanType); UpdateControls(panel, collection); } // 公共的控件更新逻辑(修复了原代码的数组越界问题) private static void UpdateControls(Panel panel, object[,] collection) { int rowCount = collection.GetLength(0); // 获取二维数组的行数 for (int i = 0; i < rowCount; i++) { var controlName = collection[i, 0].ToString(); var control = panel.Controls[controlName]; if (control is TextBox textBox) { textBox.Text = collection[i, 1].ToString(); } else if (control is NumericUpDown numUpDown) { numUpDown.Value = Convert.ToDecimal(collection[i, 1]); } } } // 调用方式(直观且类型安全) Reset(myPanel, new ShalvarResetParameters { ShalvarType = ShalvarType.TypeA }); Reset(myPanel, new DamanResetParameters { DamanType = DamanType.TypeB });
方案三:构建器模式(最贴近"注解式"调用)
如果想要更流畅的链式配置体验,可以用构建器模式:
public class ResetBuilder { private readonly Panel _panel; private readonly formulaType _formulaType; private ShalvarType _shalvarType = 0; private DamanType _damanType = 0; // 其他枚举参数... public ResetBuilder(Panel panel, formulaType formulaType) { _panel = panel; _formulaType = formulaType; } public ResetBuilder WithShalvarType(ShalvarType type) { _shalvarType = type; return this; } public ResetBuilder WithDamanType(DamanType type) { _damanType = type; return this; } // 其他WithXXX方法... public void Execute() { object[,] collection = null; switch (_formulaType) { case formulaType.Shalvar: collection = shalvarFurmula(_shalvarType); break; case formulaType.Daman: collection = damanFurmula(_damanType); break; // 其他case分支... } UpdateControls(_panel, collection); } // 公共控件更新方法(同方案二) private static void UpdateControls(Panel panel, object[,] collection) { int rowCount = collection.GetLength(0); for (int i = 0; i < rowCount; i++) { var controlName = collection[i, 0].ToString(); var control = panel.Controls[controlName]; if (control is TextBox textBox) { textBox.Text = collection[i, 1].ToString(); } else if (control is NumericUpDown numUpDown) { numUpDown.Value = Convert.ToDecimal(collection[i, 1]); } } } } // 调用方式(完全类似"注解式"链式配置) new ResetBuilder(myPanel, formulaType.Shalvar) .WithShalvarType(ShalvarType.TypeA) .Execute(); new ResetBuilder(myPanel, formulaType.Astin) .WithAstinType(AstinType.MyType) .Execute();
内容的提问来源于stack exchange,提问作者Mohammad Haeri
相关产品推荐
相关产品推荐

