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

时间:2019-12-14 22:21:03

标签: c# generics delegates .net-standard

我正在尝试保持代码干燥。我有5种具有相同代码量的方法,但我不想多次全部编写。以下是2个示例方法。我想知道如何将其合并为一种通用方法。那是最好的方法吗?

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)
        {

            T 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}");
            }

1 个答案:

答案 0 :(得分:0)

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

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);
}