如何避免以下重复代码

本文关键字:代码 何避免 | 更新日期: 2023-09-27 18:29:41

我写了两个看起来相似的函数,如何优化它们?

注:

1.AsyncCompletedEventArgsDownloadStringCompletedEventArgUploadStringCompletedEventArgs的基类。

2.Result属性不在AsyncCompletedEventArgs中。

3.DownloadStringCompletedEventArgs具有Error属性,如果Errornull,则尝试访问Result属性,则发生异常。

void fun1(DownloadStringCompletedEventArgs e)
{
    try
    {
        string s = e.Result;
    }
    catch (WebException eX)
    {
        HandleWebException();
    }
}
void fun2(UploadStringCompletedEventArgs e)
{
   try
   {
       string s = e.Result;
   }
   catch (WebException eX)
   {
       HandleWebException();
   }
}

如何避免以下重复代码

您的代码可能会更改为以下内容:

    void fun1(DownloadStringCompletedEventArgs e) { Process(e); }
    void fun2(UploadStringCompletedEventArgs e) { Process(e); }
    private void Process(dynamic eventArgs)
    {
        try
        {
            string s = eventArgs.Result;
        }
        catch (WebException e)
        {
            HandleWebException(e);
        }
    }

UploadStringCompletedEventArgsDownloadCompletedEventArgs都扩展了AsyncCompletedEventArgs,但遗憾的是基类没有定义Result属性。

带有结果访问器委托的TryX模式可能适用于此处:

public bool TryGetResult(Func<string> resultAccessor, out string result)
{
    try
    {
        result = resultAccessor();
        return true;
    }
    catch(WebException)
    {
        HandleWebException();
        result = null;
        return false;
    }
}
void fun1(DownloadStringCompletedEventArgs e)      
{
    string result;
    if (TryGetResult(() => e.Result, out result))
    {
        // Success
    }
}      
void fun2(UploadStringCompletedEventArgs e)      
{      
    string result;
    if (TryGetResult(() => e.Result, out result))
    {
        // Success
    }
}  

不过,我建议尝试检查AsyncCompletedEventArgs.Error,因为异常非常昂贵。

类似这样的东西:

void fun1(DownloadStringCompletedEventArgs e) 
{ 
    var result = Process<string>(e); 
    if (result != null)
    {
        // TODO your logic here
    }
}
void fun2(UploadStringCompletedEventArgs e) 
{
    var result = Process<string>(e); 
    if (result != null)
    {
        // TODO your logic here
    }
}
private T Process<T>(AsyncCompletedEventArgs result)
{
    if (result.Error != null)
        HandleWebException(result.Error);
    else if (!result.Cancelled)
    {
        //var prop = result.GetType().GetProperty("Result");
        //return (T) prop.GetValue(result, null);
        return (T) ((dynamic)result).Result;
    }
    //else // TODO handle cancelled
    return default(T);
}

也许您可以编写一个函数,该函数接受AsyncCompletedEventArgs类型的参数(您使用的两个eventArg类都继承自该参数),然后尝试在代码中将其强制转换为正确的类型。这将允许您用相同的方法完成这两项工作,但查看您的代码可能不会对您有多大好处。祝你好运