C# 不使用if/switch/三元运算符实现方法顺序依赖调用方案
实现方案
你的需求是不使用if、switch case、三元运算符实现「前序方法成功才执行后续方法」的逻辑,推荐使用异常流控制执行顺序的方案,完全符合语法限制要求,实现逻辑如下:
步骤1:调整数据访问层方法(可选,用于完全消除所有if判断)
如果要求全链路无if语句,可以修改DataContext类的ExecuteSql方法,SQL执行无数据变更时直接抛出异常,无需上层判断返回值:
public static int ExecuteSql(string sql,string connectionstring,DynamicParameters param) { int result = 0; try { using (con = new SqlConnection(connectionstring)) { // 新创建的连接默认是关闭状态,可直接删除状态判断的if语句 con.Open(); tran = StartTransaction(); result = con.Execute(sql,null,tran,0,CommandType.Text); // 执行无数据变更直接抛出异常中断流程 if(result <= 0) throw new InvalidOperationException("SQL执行无有效数据变更"); CommitTransaction(); con.Close(); } } catch (Exception ex) { RollBackTransaction(); throw ex; } finally { con.Close(); } return result; }
步骤2:修改业务层方法,失败不吞异常
原有CountryBE类的方法捕获异常后仅打日志、返回0,会导致上层无法感知操作失败,调整为异常捕获后重新抛出,中断执行流:
namespace BusinessEntity { public class CountryBE { public static int UpdateCountry(IConfiguration _iconfiguration) { int result = 0; try { Logger.LogMessage(MethodBase.GetCurrentMethod().Name + "" + "Started"); result = CountryDE.UpdateCountry(_iconfiguration); return result; } catch (Exception ex) { Logger.LogException(ex.Message); // 重新抛出异常,中断上层执行 throw; } } public static int AddCountries(IConfiguration _iconfiguration) { int result = 0; try { Logger.LogMessage(MethodBase.GetCurrentMethod().Name + "" + "Started"); result = CountryDE.AddCountries(_iconfiguration); return result; } catch (Exception ex) { Logger.LogException(ex.Message); // 重新抛出异常,中断上层执行 throw; } } // GetCountry方法保持不变 public static DataTable GetCountry(IConfiguration _iconfiguration) { try { Logger.LogMessage(MethodBase.GetCurrentMethod().Name + "" + "Started"); DataTable dt = CountryDE.GetCountry(_iconfiguration); return dt; } catch (Exception ex) { throw ex; } } } }
步骤3:调整Program.cs执行逻辑,完全消除分支判断
直接按顺序调用三个方法,前序方法抛出异常后后续方法自动不会执行,仅用try-catch处理失败场景,无任何禁止使用的语法:
namespace ConsoleApp1 { class Program { private static IConfiguration _iconfiguration; static void Main(string[] args) { GetAppSettingsFile(); var servicesProvider = BuildDi(_iconfiguration); using(servicesProvider as IDisposable) { servicesProvider.GetRequiredService<Logger>(); } ExecuteWorkflow(); } // 原有BuildDi、GetAppSettingsFile方法保持不变 public static IServiceProvider BuildDi(IConfiguration config) { return new ServiceCollection() .AddTransient<Logger>(). AddLogging(loggingBuilder => { loggingBuilder.ClearProviders(); loggingBuilder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Information); loggingBuilder.AddNLog(config); }).BuildServiceProvider(); } static void GetAppSettingsFile() { var builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); _iconfiguration = builder.Build(); } // 无分支的工作流执行方法 static void ExecuteWorkflow() { try { // 按顺序调用,前一个失败抛出异常就不会执行后面的方法 CountryBE.UpdateCountry(_iconfiguration); CountryBE.AddCountries(_iconfiguration); GetCountryDetails(); } catch { Console.WriteLine("Not Updated"); } } static void GetCountryDetails() { Console.WriteLine("Get Countries"); DataTable dt = CountryBE.GetCountry(_iconfiguration); foreach(DataRow dr in dt.Rows) { Console.WriteLine(dr["country"].ToString()); } Console.WriteLine("Press any key to stop."); Console.ReadKey(); } } }
额外优化提示
原有DataContext类使用了静态的SqlConnection和SqlTransaction,存在线程安全问题,多线程并发调用时会出现事务混乱、连接被提前释放等异常,建议改为每次操作单独创建事务对象,不要用静态变量存储连接和事务实例。
内容的提问来源于stack exchange,提问作者aniket narvankar
相关产品推荐
相关产品推荐

