FormattedException 而不是 throw new Exception(string.Format(...)) 在 .NET 中 [英] FormattedException instead of throw new Exception(string.Format(...)) in .NET

查看:28
本文介绍了FormattedException 而不是 throw new Exception(string.Format(...)) 在 .NET 中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在想一个很好的通用异常对象来代替 throw new Exception(string.Format("...",...)),以简化并加快速度起来这样的对象.缓慢的 String.Format() 格式化应该延迟到 Message 属性被调用.序列化也有点冒险.而且,这样的对象以后可以实现本地化.

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 而不是 throw new Exception(string.Format(...)) 在 .NET 中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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