FormattedException,而不是扔在.NET新的异常(的String.format(...)) [英] FormattedException instead of throw new Exception(string.Format(...)) in .NET

查看:121
本文介绍了FormattedException,而不是扔在.NET新的异常(的String.format(...))的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在思考一个很好的通用异常对象将取代抛出新的异常(的String.Format(...,...)),以既简化并加快这样的对象。通过格式化缓慢的String.Format()应推迟到消息属性被调用。序列化是也有点冒险。此外,这样的对象可以在以后实现国产化。

更新:这个异常应该由更具体的用户异常继承,而不是抛出本身。对不起,没有做这一点。

这是我想出了。如果有,以提高它的任何方式请评论。谢谢!

  ///<总结>
///能够延迟邮件格式的一般例外。
///继承更具体的例外情况。
///< /总结>
[Serializable接口]
公共类FormattedException:异常
{
    私人只读对象[] _arguments;
    私人只读字符串_formatStr;
    私人只读布尔_useFormat;    私人FormattedException(布尔useFormat,内心异常,字符串消息,params对象[]参数)
        :基地(信息,内部)
    {
        _useFormat = useFormat;
        _formatStr =消息;
        _arguments = ARGS;
    }    公共FormattedException()
        :这个(假,NULL,NULL,NULL)
    {}    公共FormattedException(字符串消息)
        :这个(假,空,信息,空)
    {}    公共FormattedException(字符串消息,params对象[]参数)
        :这(真实的,空,消息,参数)
    {}    公共FormattedException(例外内,字符串消息)
        :这个(假的,内在的,信息,空)
    {}    公共FormattedException(例外内,字符串消息,params对象[]参数)
        :这(真实的,内在的,消息参数)
    {}    公众覆盖字符串消息
    {
        得到
        {
            如果(!_useFormat)
                返回_formatStr;            尝试
            {
                返回的String.Format(_formatStr,_arguments);
            }
            赶上(异常前)
            {
                VAR SB =新的StringBuilder();                sb.Append(错误格式的例外:);
                sb.Append(ex.Message);
                sb.Append(\\ nFormat字符串:);
                sb.Append(_formatStr);
                如果(_arguments =空&放大器;!&放大器; _arguments.Length大于0)
                {
                    sb.Append(\\ nArguments:);
                    的for(int i = 0; I< _arguments.Length;我++)
                    {
                        如果(I 0)sb.Append(,);
                        尝试
                        {
                            sb.Append(_arguments [I]);
                        }
                        赶上(例外EX2)
                        {
                            sb.AppendFormat((参数#{0}无法显示:{1}),我,ex2.Message);
                        }
                    }
                }                返回sb.ToString();
            }
        }
    }    #区域序列化    私人常量字符串SerializationField =的formatString;    保护FormattedException(的SerializationInfo信息,的StreamingContext上下文)
        :基地(信息,上下文)
    {
        _formatStr =(字符串)info.GetValue(SerializationField的typeof(字符串));
        //为默认保留其他值
    }    公共覆盖无效GetObjectData使用(的SerializationInfo信息,的StreamingContext上下文)
    {
        base.GetObjectData(资讯,背景);
        //为了避免任何序列化问题与参数对象格式的消息现在
        info.AddValue(SerializationField,信息,typeof运算(字符串));
    }    #endregion
}


解决方案

这是一个有趣的想法,但不是一个好主意。之所以要创建一个自定义异常无关,与易用性 - 只有创造如果有人要捕获该异常类型,做不同的事情有一个自定义异常

而不是一个自定义异常的,也许你可以创建一个扩展方法。

I have been thinking of a good generic exception object that would replace throw new Exception(string.Format("...",...)), to both simplify and also to speed up such objects. The formatting by slow String.Format() should be delayed until Message property is called. Serialization is also somewhat risky. Also, such object could later implement localization.

Update: This exception should be inherited by more specific user exceptions, not thrown itself. Sorry for not making this clear.

This is what I have come up with. Please comment if there are any ways to improve it. Thanks!

/// <summary>
/// Generic exception capable of delayed message formatting.
/// Inherit for more specific exceptions.
/// </summary>
[Serializable]
public class FormattedException : Exception
{
    private readonly object[] _arguments;
    private readonly string _formatStr;
    private readonly bool _useFormat;

    private FormattedException(bool useFormat, Exception inner, string message, params object[] args)
        : base(message, inner)
    {
        _useFormat = useFormat;
        _formatStr = message;
        _arguments = args;
    }

    public FormattedException()
        : this(false, null, null, null)
    {}

    public FormattedException(string message)
        : this(false, null, message, null)
    {}

    public FormattedException(string message, params object[] args)
        : this(true, null, message, args)
    {}

    public FormattedException(Exception inner, string message)
        : this(false, inner, message, null)
    {}

    public FormattedException(Exception inner, string message, params object[] args)
        : this(true, inner, message, args)
    {}

    public override string Message
    {
        get
        {
            if (!_useFormat)
                return _formatStr;

            try
            {
                return string.Format(_formatStr, _arguments);
            }
            catch (Exception ex)
            {
                var sb = new StringBuilder();

                sb.Append("Error formatting exception: ");
                sb.Append(ex.Message);
                sb.Append("\nFormat string: ");
                sb.Append(_formatStr);
                if (_arguments != null && _arguments.Length > 0)
                {
                    sb.Append("\nArguments: ");
                    for (int i = 0; i < _arguments.Length; i++)
                    {
                        if (i > 0) sb.Append(", ");
                        try
                        {
                            sb.Append(_arguments[i]);
                        }
                        catch (Exception ex2)
                        {
                            sb.AppendFormat("(Argument #{0} cannot be shown: {1})", i, ex2.Message);
                        }
                    }
                }

                return sb.ToString();
            }
        }
    }

    #region Serialization

    private const string SerializationField = "FormatString";

    protected FormattedException(SerializationInfo info, StreamingContext context)
        : base(info, context)
    {
        _formatStr = (string) info.GetValue(SerializationField, typeof (string));
        // Leave other values at their default
    }

    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        base.GetObjectData(info, context);
        // To avoid any serialization issues with param objects, format message now
        info.AddValue(SerializationField, Message, typeof (string));
    }

    #endregion
}

解决方案

It's an interesting thought, but not a good idea. The reason to create a custom exception have nothing to do with ease of use - only create a custom exception if someone is going to catch that exception type and do something different with it.

Instead of a custom exception, maybe you can create an extension method.

这篇关于FormattedException,而不是扔在.NET新的异常(的String.format(...))的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆