如何避免以下重复代码?

时间:2012-03-30 11:41:55

标签: c# windows-phone-7 optimization webclient

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

注意:

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

4 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:2)

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,因为例外情况非常昂贵。

答案 2 :(得分:1)

这样的事情:

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

答案 3 :(得分:0)

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