C#:更好的编码方式?

时间:2011-03-01 11:19:02

标签: c# if-statement

我有一个代码块来处理我的应用程序中的异常,它使用if / else块来获取消息内容。
我的代码如下:

// define variable to hold exceptions...
var exceptionMessage = new StringBuilder();  
// based on the exception type...  
if (expType == typeof(EntityValidationException))  
{  
    // append the relevant message to the text...  
    exceptionMessage.Append(exception.InnerException.Message);  
}  
else if (expType == typeof(ValidationException))  
{  
    // This is the type of error generated when entities are validated  
    var validationException = (ValidationException)exception;  
    exceptionMessage.Append(validationException.InnerException.Message);  
}  
else if (expType == typeof(DomainSecurityException))  
{  
    // These are security breaches  
    var domainSecurityException = (DomainSecurityException)exception;  
    exceptionMessage.Append(domainSecurityException.InnerException.Message);  
}  
else if (expType == typeof(DomainInternalMessageException))  
{  
    // These are the type of errors generated a System.Exception occurs and is  
    // converted by the exception handling policy to a more friendly format  
    var domainInternalMessageException = (DomainInternalMessageException)exception;  
    exceptionMessage.Append(domainInternalMessageException.ExceptionMessage);  
}
else  
{  
    exceptionMessage.AppendFormat(ErrorMessagesRes.Standard_Error_Format, "Unknown error", exception.InnerException.Message);   
}  
// this shows the message as an alert popup...  
this.DisplayJavascriptMessage(exceptionMessage.ToString());

这与原始版本相比有所改进,但只是想看看这个代码是否有更整洁,更可重复的解决方案。
提前谢谢你 马丁

5 个答案:

答案 0 :(得分:5)

假设这是一个传递异常对象的例程(并没有直接参与try catch块),并假设“异常”对象最终从Exception派生,你可以简单地简化你的代码

// define variable to hold exceptions...
            var exceptionMessage = new StringBuilder();

            // based on the exception type...  
            if (exception is EntityValidationException || exception is ValidationException || exception is DomainSecurityException)
            {
                // append the relevant message to the text...  
                exceptionMessage.Append(exception.InnerException.Message);
            }

            else if (expType == typeof(DomainInternalMessageException))
            {
                // These are the type of errors generated a System.Exception occurs and is  
                // converted by the exception handling policy to a more friendly format  
                var domainInternalMessageException = (DomainInternalMessageException)exception;
                exceptionMessage.Append(domainInternalMessageException.ExceptionMessage);
            }
            else
            {
                exceptionMessage.AppendFormat(ErrorMessagesRes.Standard_Error_Format, "Unknown error", exception.InnerException.Message);
            }
            // this shows the message as an alert popup...  
            this.DisplayJavascriptMessage(exceptionMessage.ToString());

答案 1 :(得分:2)

    var exceptionMessage = new StringBuilder();  

    try
    {
    }
    catch(EntityValidationException exc)
    {  
        exceptionMessage.Append(exc.InnerException.Message);  
    }  
    catch(ValidationException exc)  
    {  
        exceptionMessage.Append(exc.InnerException.Message);  
    }  
    ....

确保catch块的顺序从最不通用到最通用。

答案 2 :(得分:2)

public static Exception On<T>(this Exception e, Action<T> action)
{
    if(e is T)
        action((T)e);

    return e;
}

exception.
    On<ValidationException>(e => exceptionMessage.Append(e.InnerException.Message)).
    On<DomainInternalMessageException>(e => ...);

答案 3 :(得分:1)

每当我看到那些if else if陈述时,我认为这必须更容易。在某些情况下,switch语句可以提供帮助,但正如this question所述,无法打开Type。

我常用的另一种解决方法是某种Dictionary<Type, something>something取决于我想做什么。对于你的案例,可能最匹配的构造类似Dictionary<Type, Func<Exception, string>>,可以在你的情况下使用这样的东西:

Dictionary<Type, Func<Exception, string>> _FunctorsForType;

private void InitializeFunctorsForType()
{
    _FunctorsForType = new Dictionary<Type, Func<Exception, string>>();

    // Add a normal function
    _FunctorsForType.Add(typeof(ArgumentException), (Func<Exception, string>)ForArgumentException);

    // Add as lambda
    _FunctorsForType.Add(typeof(InvalidCastException), (ex) =>
        {
            // ToDo: Whatever you like
            return ex.Message;
        });
}

private string ForArgumentException(Exception ex)
{
    var argumentException = ex as ArgumentException;

    if (argumentException == null)
    {
        throw new ArgumentException("Exception must be of type " + typeof(ArgumentException).Name);
    }

    // ToDo: Whatever you like
    return ex.Message;
}

private void Usage(Type type)
{
    Func<Exception, string> func;

    if (!_FunctorsForType.TryGetValue(type, out func))
    {
        throw new ArgumentOutOfRangeException("Exception type " + type.Name + " is not supported.");
    }

    var message = func(new NullReferenceException());

    // ToDo: Whatever you have to do with your message
}

因此,通过这种结构,您无需将所有智能放入一个大的if-else语句中。相反,您可以将它们放在单独的函数中(可能在不同的类中),以便更好地组织如何处理您希望支持的每种类型。

答案 4 :(得分:0)

string exceptionMessage;
if (expType == typeof(EntityValidationException) || 
    expType == typeof(ValidationException) ||
    expType == typeof(DomainSecurityException))
  exceptionMessage = exception.InnerException.Message;
else if (expType == typeof(DomainInternalMessageException))  
 exceptionMessage = ((DomainInternalMessageException)exception).ExceptionMessage;
else  
 exceptionMessage = string.Format(ErrorMessagesRes.Standard_Error_Format, "Unknown error", exception.InnerException.Message);  

this.DisplayJavascriptMessage(exceptionMessage);

有点压缩,没有评论。