简体   繁体   English

C#:更好的编码方式?

[英]C# : Better way to code this?

I have a block of code to handle exceptions in my application, which uses an if/else block to obtain the message content. 我有一个代码块来处理我的应用程序中的异常,它使用if / else块来获取消息内容。
My code is as follows: 我的代码如下:

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

This has been improved from the original version, but just want to see if there is a neater, more re-usable solution to this code. 这已从原始版本改进,但只是想看看是否有更简洁,更可重用的解决方案。
Thanks in advance 提前致谢
Martin 马丁

Assuming that this is a routine which gets passed an exception object (and is not directly involved in a try catch block) and assuming the "exception" object derives eventually from Exception, you could concise your code a bit to do 假设这是一个传递异常对象的例程(并没有直接参与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());
    var exceptionMessage = new StringBuilder();  

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

Make sure the catch blocks come in proper order from least generic to most generic. 确保catch块的顺序从最不通用到最通用。

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 => ...);

Whenever i see those if else if statements i think this must be done easier. 每当我看到那些if else if语句我认为这必须更容易。 In some cases the switch statement can help, but as this question already stated, it is not possible to switch on Type. 在某些情况下,switch语句可以提供帮助,但正如此问题已经说明的那样,无法打开Type。

So another workaround i commonly use is some kind of Dictionary<Type, something> . 所以我经常使用的另一种解决方法是某种Dictionary<Type, something> Where something depends on what i'd like to do. something取决于我想做什么。 The maybe best matching construct for your case would something like Dictionary<Type, Func<Exception, string>> which could be used in your case something like this: 对于你的案例,最好的匹配构造可能类似于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
}

So with this construction you don't have to put all your intelligence into a big if-else statement. 因此,通过这种结构,您无需将所有智能放入一个大的if-else语句中。 Instead you can put them in separate functions (maybe in different classes) to get a better organization of how to handle each type you like to support. 相反,您可以将它们放在单独的函数中(可能在不同的类中),以便更好地组织如何处理您希望支持的每种类型。

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

A little compressed, and without comments. 有点压缩,没有评论。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM