C#初学者求优化:类型检查与转换逻辑的复用实现方案
解决C#中重复类型检查与转换的复用方案
嘿,作为刚入门C#的开发者,能意识到要把重复代码封装复用,这思路真的超赞!咱们来把你ForEach里那堆类型检查+转换的逻辑好好封装一下,让代码清爽不少。
先还原下你现在可能的代码场景(应该和这个差不多对吧?):
public interface Example { /* 接口成员 */ } public class ConcreteExample1 : Example { /* 实现 */ } public class ConcreteExample2 : Example { /* 实现 */ } // 你现在的循环代码 List<Example> examples = GetExamples(); examples.ForEach(example => { if (example is ConcreteExample1 ex1) { // 针对ConcreteExample1的业务逻辑 Console.WriteLine($"处理ConcreteExample1:{ex1.Id}"); } else if (example is ConcreteExample2 ex2) { // 针对ConcreteExample2的业务逻辑 Console.WriteLine($"处理ConcreteExample2:{ex2.Name}"); } });
这种is检查+类型转换的逻辑如果在多个地方出现,确实很冗余,咱们用扩展方法来封装最合适,毕竟扩展方法能直接挂在Example接口上,调用起来特别直观。
方案1:通用单类型处理扩展方法
先写一个静态类来放扩展方法(记得要放在能被你的业务代码访问到的命名空间下):
public static class ExampleExtensions { // 针对无返回值的处理逻辑 public static void Handle<T>(this Example example, Action<T> handler) where T : Example { // 把类型检查和转换逻辑封装在这里 if (example is T typedInstance) { handler(typedInstance); } } // 可选:如果需要有返回值的处理逻辑 public static TResult Handle<T, TResult>(this Example example, Func<T, TResult> handler, TResult defaultValue = default) where T : Example { return example is T typedInstance ? handler(typedInstance) : defaultValue; } }
现在你的循环代码可以改成这样:
examples.ForEach(example => { // 处理ConcreteExample1 example.Handle<ConcreteExample1>(ex1 => { Console.WriteLine($"处理ConcreteExample1:{ex1.Id}"); }); // 处理ConcreteExample2 example.Handle<ConcreteExample2>(ex2 => { Console.WriteLine($"处理ConcreteExample2:{ex2.Name}"); }); });
这样一来,所有重复的is检查和转换都被封装到Handle方法里了,你只需要专注于业务逻辑就行。
方案2:多类型分支处理扩展方法
如果你的场景里每次都是同时处理这两个类型(不会单独处理其中一个),还可以封装一个更针对性的方法,让代码更简洁:
public static class ExampleExtensions { public static void HandleExamples(this Example example, Action<ConcreteExample1> handleConcrete1, Action<ConcreteExample2> handleConcrete2, Action<Example> handleDefault = null) { switch (example) { case ConcreteExample1 ex1: handleConcrete1(ex1); break; case ConcreteExample2 ex2: handleConcrete2(ex2); break; default: handleDefault?.Invoke(example); break; } } }
调用的时候就更清爽了:
examples.ForEach(example => example.HandleExamples( ex1 => Console.WriteLine($"处理ConcreteExample1:{ex1.Id}"), ex2 => Console.WriteLine($"处理ConcreteExample2:{ex2.Name}"), // 可选:默认处理逻辑 _ => Console.WriteLine("处理未知的Example类型") ));
用switch模式匹配比if-else更清晰,以后如果新增Example的实现类,只需要在这个方法里加一个case分支就行,所有调用的地方都能直接复用。
为啥这么做更好?
- 减少重复代码:把类型检查+转换的逻辑只写一次,多处复用
- 代码更易读:业务逻辑和类型判断逻辑分离,一眼就能看到你要处理什么类型、做什么操作
- 维护更方便:以后如果类型结构变了,只需要修改封装的方法,不用改所有调用的地方
内容的提问来源于stack exchange,提问作者Frontear
相关产品推荐
相关产品推荐

