有没有办法在 c# 中将一个方法传递给另一个方法,最好的方法是什么?

Is there a way to pass a method into another method in c# and what's the best way to do it?

我正在努力让我的代码保持干燥。我有 5 种方法,它们的代码量相同,但我不想多次编写它们。以下是 2 个示例方法。我想知道如何将它合并为 1 个通用方法。这是最好的方法吗?

public async Task<PlaylistListResponse> GetPlaylistsFromChannel(string channelID, bool forceRefresh = false)
{
    string barrelURL = "GetPlaylistsFromChannel" + channelID.Trim();
    PlaylistListResponse results = default;

    if(forceRefresh != true)
    {
        results = GetCached<PlaylistListResponse>(barrelURL);
    }
    else
    {
        try
        {
            if (object.Equals(results, default(PlaylistListResponse)))
            {
                var playlistFromChannelRequest = youtubeService.Playlists.List("id");
                playlistFromChannelRequest.ChannelId = channelID;
                playlistFromChannelRequest.MaxResults = 50;
                results = await playlistFromChannelRequest.ExecuteAsync();
                Barrel.Current.Add(barrelURL, results, TimeSpan.FromDays(30));
            }

            return results;
        }
        catch (Exception ex)
        {
            Crashes.TrackError(ex);
        }
    }

    return results;
}

public async Task<PlaylistListResponse> GetPlaylistsFromChannel(string channelID, bool forceRefresh = false)
{
    string barrelURL = "GetPlaylistsFromChannel" + channelID.Trim();
    PlaylistListResponse results = default;

    if (forceRefresh != true)
    {
        results = GetCached<PlaylistListResponse>(barrelURL);
    }
    else
    {
        try
        {
            if (object.Equals(results, default(PlaylistListResponse)))
            {
                var videosFromPlaylistRequest = youtubeService.PlaylistItems.List("snippet");
                videosFromPlaylistRequest.PlaylistId = playlistID;
                videosFromPlaylistRequest.MaxResults = 50;

                results = await videosFromPlaylistRequest.ExecuteAsync();
                Barrel.Current.Add(barrelURL, results, TimeSpan.FromDays(30));
            }

            return results;
        }
        catch (Exception ex)
        {
            Crashes.TrackError(ex);
        }
    }

    return results;
}

我尝试创建一个通用方法,但找不到对其进行更改的方法,因为我不想要大量 if 语句。

public async Task<T> GetAsync<T>(string barrelURL, int days = 7, bool forceRefresh = false)
{
    results = default(T);

    if (!CrossConnectivity.Current.IsConnected)
        results = Barrel.Current.Get<T>(barrelURL);

    if (!forceRefresh && !Barrel.Current.IsExpired(barrelURL))
        results = Barrel.Current.Get<T>(barrelURL);

    try
    {
        if (object.Equals(results, default(T)))
        {
            //myMethodsCode??
            Barrel.Current.Add(barrelURL, results, TimeSpan.FromDays(days));
        }

        return results;
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Unable to get information from server {ex}");
    }
}

这个问题的一个可能的解决方案是创建一个通用方法并将代表不同部分的委托传递给它。

public async Task<T> GetFromChannel<T>(
    string channelID,
    Func<Task<T>> resultGetter,
    bool forceRefresh = false)
{
    string barrelURL = "GetPlaylistsFromChannel" + channelID.Trim();
    T results = default;

    if (forceRefresh != true)
    {
        results = GetCached<T>(barrelURL);
    }
    else
    {
        try
        {
            if (object.Equals(results, default(T)))
            {
                results = await resultGetter();
                Barrel.Current.Add(barrelURL, results, TimeSpan.FromDays(30));
            }

            return results;
        }
        catch (Exception ex)
        {
            Crashes.TrackError(ex);
        }
    }

    return results;
}

然后您可以使用其他方法或 lambda 表达式插入不同的部分,例如:

public Task<PlaylistListResponse> GetPlaylistsFromChannel(
    string channelID,
    bool forceRefresh = false)
{
    return GetFromChannel<PlaylistListResponse>(
        channelID,
        async () =>
        {
            var videosFromPlaylistRequest = youtubeService.PlaylistItems.List("snippet");
            videosFromPlaylistRequest.PlaylistId = playlistID;
            videosFromPlaylistRequest.MaxResults = 50;

            return await videosFromPlaylistRequest.ExecuteAsync();
        },
        forceRefresh);
}