C#中替代Python Decorators的方案:银行账户PIN重试实现
给C#银行账户方法添加PIN重试机制的替代方案
方案1:提取通用重试逻辑到辅助类(最推荐,轻量可控)
把PIN验证和重试逻辑封装成独立的泛型辅助方法,业务方法只需传入验证逻辑和自身业务代码,完全避免重复编写重试逻辑。
辅助类实现
public static class PinRetryHelper { // 无返回值方法的重试封装 public static void ExecuteWithPinRetry(Func<string, bool> validatePin, Action operation, int maxRetries = 3) { for (int retry = 0; retry < maxRetries; retry++) { Console.Write("请输入PIN码:"); string inputPin = Console.ReadLine(); if (validatePin(inputPin)) { operation(); return; } Console.WriteLine($"PIN码错误,剩余重试次数:{maxRetries - retry - 1}"); } Console.WriteLine("重试次数用完,操作失败"); } // 带返回值方法的重试封装 public static T ExecuteWithPinRetry<T>(Func<string, bool> validatePin, Func<T> operation, int maxRetries = 3) { for (int retry = 0; retry < maxRetries; retry++) { Console.Write("请输入PIN码:"); string inputPin = Console.ReadLine(); if (validatePin(inputPin)) { return operation(); } Console.WriteLine($"PIN码错误,剩余重试次数:{maxRetries - retry - 1}"); } Console.WriteLine("重试次数用完,操作失败"); return default(T); } }
Account类中的用法
public class Account { private string _pin = "1234"; // 实际场景需加密存储 private decimal _balance = 1000; public void DepositMoney(decimal amount) { PinRetryHelper.ExecuteWithPinRetry( validatePin: input => input == _pin, operation: () => { _balance += amount; Console.WriteLine($"存款成功,当前余额:{_balance}"); } ); } public decimal CheckBalance() { return PinRetryHelper.ExecuteWithPinRetry( validatePin: input => input == _pin, operation: () => { Console.WriteLine($"当前余额:{_balance}"); return _balance; } ); } }
方案2:使用泛型委托包装器
如果希望直接把业务方法包装成带重试的版本,可以写一个包装方法,返回注入了重试逻辑的委托。
包装器实现
public static class PinRetryWrapper { public static Action WrapActionWithPinRetry(Action action, Func<string, bool> validatePin, int maxRetries = 3) { return () => { for (int retry = 0; retry < maxRetries; retry++) { Console.Write("请输入PIN码:"); string inputPin = Console.ReadLine(); if (validatePin(inputPin)) { action(); return; } Console.WriteLine($"PIN码错误,剩余重试次数:{maxRetries - retry - 1}"); } Console.WriteLine("操作失败"); }; } public static Func<T> WrapFuncWithPinRetry<T>(Func<T> func, Func<string, bool> validatePin, int maxRetries = 3) { return () => { for (int retry = 0; retry < maxRetries; retry++) { Console.Write("请输入PIN码:"); string inputPin = Console.ReadLine(); if (validatePin(inputPin)) { return func(); } Console.WriteLine($"PIN码错误,剩余重试次数:{maxRetries - retry - 1}"); } Console.WriteLine("操作失败"); return default(T); }; } }
Account类中的用法
public class Account { private string _pin = "1234"; private decimal _balance = 1000; public Action DepositWithRetry(decimal amount) { return PinRetryWrapper.WrapActionWithPinRetry( () => { _balance += amount; Console.WriteLine($"存款成功,余额:{_balance}"); }, input => input == _pin ); } public Func<decimal> CheckBalanceWithRetry() { return PinRetryWrapper.WrapFuncWithPinRetry( () => { Console.WriteLine($"余额:{_balance}"); return _balance; }, input => input == _pin ); } }
调用示例
var account = new Account(); account.DepositWithRetry(500)(); // 执行带重试的存款操作 var balance = account.CheckBalanceWithRetry()(); // 执行带重试的查余额操作
方案3:模板方法模式
如果后续有多个类似账户类型,可以用模板方法模式,把重试逻辑放到基类,子类专注实现具体业务逻辑。
基类与子类实现
public abstract class BaseAccount { protected string _pin; protected decimal _balance; protected BaseAccount(string pin, decimal initialBalance) { _pin = pin; _balance = initialBalance; } // 模板方法:封装重试逻辑 protected void ExecuteWithPinRetry(Action operation) { for (int retry = 0; retry < 3; retry++) { Console.Write("请输入PIN码:"); string inputPin = Console.ReadLine(); if (inputPin == _pin) { operation(); return; } Console.WriteLine($"PIN错误,剩余重试次数:{2 - retry}"); } Console.WriteLine("操作失败"); } protected T ExecuteWithPinRetry<T>(Func<T> operation) { for (int retry = 0; retry < 3; retry++) { Console.Write("请输入PIN码:"); string inputPin = Console.ReadLine(); if (inputPin == _pin) { return operation(); } Console.WriteLine($"PIN错误,剩余重试次数:{2 - retry}"); } Console.WriteLine("操作失败"); return default(T); } // 子类需实现的抽象业务方法 public abstract void DepositMoney(decimal amount); public abstract decimal CheckBalance(); } public class SavingsAccount : BaseAccount { public SavingsAccount(string pin, decimal initialBalance) : base(pin, initialBalance) { } public override void DepositMoney(decimal amount) { ExecuteWithPinRetry(() => { _balance += amount; Console.WriteLine($"存款成功,当前余额:{_balance}"); }); } public override decimal CheckBalance() { return ExecuteWithPinRetry(() => { Console.WriteLine($"当前余额:{_balance}"); return _balance; }); } }
内容的提问来源于stack exchange,提问作者Imaginary
相关产品推荐
相关产品推荐

