You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#不同类复用同名方法实现差异化逻辑的优化咨询

优化方案:让生日提醒方法适配多场景,避免重复代码

核心问题拆解

当前RemindPersonForBirthday方法在两种场景下需求矛盾:

  • 每日循环(InfinityLoop调用):需要遍历所有用户,检查生日/次日生日并发送提醒
  • 用户选日期(PickDate调用):只需要检查当前操作的用户,验证选中日期是否触发提醒

通过拆分核心逻辑+参数控制范围的方式,既能复用代码,又能满足不同场景的需求。


1. 重构ReminderBack类

将单个用户的生日检查逻辑抽离为私有方法,公共方法通过参数控制检查范围:

public static class ReminderBack
{
    // 核心逻辑:检查单个用户的生日并发送对应消息
    private static async Task CheckSingleUserBirthday(ITelegramBotClient botClient, Update update, string userName, DateTime userBirthDate)
    {
        var currDate = DateTime.Today;
        if (userBirthDate.Month == currDate.Month && userBirthDate.Day == currDate.Day)
        {
            var message = $"Today is {userName}'s birthday!";
            await PRTelegramBot.Helpers.Message.Send(botClient, update, message);
        }
        else if (userBirthDate.Month == currDate.Month && userBirthDate.Day == currDate.Day + 1)
        {
            var message = $"{userName}'s birthday is tomorrow!";
            await PRTelegramBot.Helpers.Message.Send(botClient, update, message);
        }
    }

    // 公共方法:支持检查单个用户或所有用户
    public static async Task RemindPersonForBirthday(ITelegramBotClient botClient, Update update, string targetUserName = null)
    {
        var cache = update.GetCacheData<UserCache>();
        
        if (!string.IsNullOrEmpty(targetUserName))
        {
            // 只检查指定用户
            if (cache.ScheduleDict.TryGetValue(targetUserName, out var birthDate))
            {
                await CheckSingleUserBirthday(botClient, update, targetUserName, birthDate);
            }
            return;
        }

        // 遍历所有用户(默认逻辑,适配每日循环)
        foreach (var user in cache.ScheduleDict)
        {
            await CheckSingleUserBirthday(botClient, update, user.Key, user.Value);
        }
    }
}

2. 修改InfinityLoop的调用逻辑

保持原有遍历所有用户的逻辑,直接调用无参重载:

public static async Task StartReminderLoop(ITelegramBotClient botClient, Update update)
{
    while (true)
    {
        if (_lastCheckDate.Day != DateTime.Now.Day)
        {
            // 无参调用,遍历所有用户
            await ReminderBack.RemindPersonForBirthday(botClient, update);
            _lastCheckDate = DateTime.Now;
        }
        await Task.Delay(CheckInterval);
    }
}

3. 修改CalendarCommandHandler.PickDate的调用逻辑

传入当前操作的用户名,只检查该用户:

public static async Task PickDate(ITelegramBotClient botClient, Update update)
{
    if (update.CallbackQuery?.Data is null)
    {
        return;
    }

    try
    {
        var command = InlineCallback<CalendarTCommand>.GetCommandByCallbackOrNull(update.CallbackQuery.Data);
        var data = command.Data.Date;

        var message = $"Picked date: <b>{data:dd.MM.yyyy}</b>";
        await PRTelegramBot.Helpers.Message.Edit(botClient, update, message);

        // 缓存日期
        var cache = update.GetCacheData<UserCache>();
        cache.DateT = data;
        var targetUserName = cache.PersonName ?? "unknown";
        CacheCommand.UpdateCache(update, targetUserName, cache.DateT);

        // 传入当前用户名,只检查该用户
        await ReminderBack.RemindPersonForBirthday(botClient, update, targetUserName);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
    }
}

额外优化建议

  • 若后续新增场景,可考虑用策略模式进一步解耦,当前场景参数控制已足够简洁
  • 给CheckSingleUserBirthday添加日志,方便排查问题
  • 已处理userName为空的边界情况,确保逻辑健壮性

内容的提问来源于stack exchange,提问作者szymptom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 02:20:13