Как избежать следующего повторного кода? - PullRequest
2 голосов
/ 30 марта 2012

Я написал две функции, которые похожи, как я могу их оптимизировать?

Примечание:

1. AsyncCompletedEventArgs - это базовый класс DownloadStringCompletedEventArg и UploadStringCompletedEventArgs.

2. Result свойство не входит в AsyncCompletedEventArgs.

3. DownloadStringCompletedEventArgs имеет свойство Error, если Error равно null, попробуйте получить доступ к свойству 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 ]

4 голосов
/ 30 марта 2012

Ваш код может быть изменен на что-то вроде ниже:

    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);
        }
    }
2 голосов
/ 30 марта 2012

UploadStringCompletedEventArgs и DownloadCompletedEventArgs оба расширяются AsyncCompletedEventArgs, но, к сожалению, базовый класс не определяет свойство Result.

A 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 , хотя исключения довольно дорогие.

1 голос
/ 30 марта 2012

Примерно так:

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);
}
0 голосов
/ 30 марта 2012

Возможно, вы могли бы написать функцию, которая принимает параметр типа AsyncCompletedEventArgs (от которого наследуются оба используемых вами класса EventArg), а затем попытаться привести его к правильному типу в вашем коде. Это позволит вам выполнить оба в одном и том же методе, но, глядя на ваш код, это, вероятно, не принесет вам большой пользы. Удачи!

...