7

可以说我想做一些自定义例外。我想拥有更多。我可以为每个新异常创建一个新类,但是还有另一种方法吗?如果我必须总是创建一个新类,在哪里存储它们?它只是在项目的根文件夹中看起来不太好。

Ahm 和另一个问题:如果某些异常是相同的,我该怎么办,只是异常的名称发生了一点变化?假设异常 A 看起来像这样:

    [Serializable()]
    public class ExceptionA: Exception, ISerializable
    {
        public ExceptionA() : base() { }
        public ExceptionA(string message) : base(message) { }
        public ExceptionA(string message, System.Exception inner) : base(message, inner) { }
        public ExceptionA(SerializationInfo info, StreamingContext context) : base(info, context) { }
    }
}

另一个是一样的,只是另一个名字:

    [Serializable()]
    public class ExceptionB: Exception, ISerializable
    {
        public ExceptionB() : base() { }
        public ExceptionB(string message) : base(message) { }
        public ExceptionB(string message, System.Exception inner) : base(message, inner) { }
        public ExceptionB(SerializationInfo info, StreamingContext context) : base(info, context) { }
    }
}

等等。我真的必须总是创建一个新类并粘贴相同的代码吗?有什么建议么?

4

3 回答 3

9

我可以为每个新异常创建一个新类,但是还有另一种方法吗?

不,没有别的办法。如果你想创建一个新的异常类型,你需要一个新的类。

在哪里存放它们?

在所有需要使用它们的代码都可以访问的位置。

如果某些异常是相同的,我该怎么办,只是异常的名称发生了一点变化?

是的,仍然需要创建一个新类 - 尽管您可以从现有异常类派生新类。

于 2012-09-06T11:05:13.880 回答
2

通常,对于这样的事情,我会创建一个项目或名称空间,其中包含将在整个项目/解决方案中使用的所有这些自定义异常(甚至枚举)。

这给了我一个单一的参考点/组装参考。

对于您关于具有相同“外观”的异常的问题,我将创建一个基类,该基类可以由“名称略有不同”的其他异常继承。

于 2012-09-06T11:04:50.047 回答
1

您必须每次都创建新的异常,因为这就是 catch() 在 try ... catch 块中捕获特定异常类型的工作方式。但我真的很喜欢通过 C# 书从 CLR 采取的下一种方法:

public abstract class ExceptionArgs
{
    public string Message { get { return string.Empty; } }
}

[Serializable]
public class Exception<TExceptionArgs> : Exception, ISerializable
   where TExceptionArgs : ExceptionArgs
{

    private const String c_args = "Args";  // For (de)serialization
    private readonly TExceptionArgs m_args;

    public TExceptionArgs Args { get { return m_args; } }
    public Exception(String message = null, Exception innerException = null)
        : this(null, message, innerException) { }

    public Exception(TExceptionArgs args, String message = null,
       Exception innerException = null)
        : base(message, innerException) { m_args = args; }

    [SecurityPermission(SecurityAction.LinkDemand,
       Flags = SecurityPermissionFlag.SerializationFormatter)]
    protected Exception(SerializationInfo info, StreamingContext context)
        : base(info, context)
    {
        m_args = (TExceptionArgs)info.GetValue(c_args, typeof(TExceptionArgs));
    }

    [SecurityPermission(SecurityAction.LinkDemand,
       Flags = SecurityPermissionFlag.SerializationFormatter)]
    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue(c_args, m_args);
        base.GetObjectData(info, context);
    }

    public override String Message
    {
        get
        {
            String baseMsg = base.Message;
            return (m_args == null) ? baseMsg : baseMsg + " (" + m_args.Message + ")";
        }
    }

    public override Boolean Equals(Object obj)
    {
        Exception<TExceptionArgs> other = obj as Exception<TExceptionArgs>;
        if (obj == null) return false;
        return Object.Equals(m_args, other.m_args) && base.Equals(obj);
    }
    public override int GetHashCode() { return base.GetHashCode(); }
}

现在将能够为这样的异常创建新的参数:

public class ExceptionAExceptionArgs : ExceptionArgs
{
    //may add some properties if required here
}

并像这样捕获“新异常”:

try
{
   //do something here...
}
catch (Exception<ExceptionAExceptionArgs> ex)
{
}

我会让你编写更少的代码来创建新的异常。
请注意:如果您想创建有一个基本异常类和几个子异常类的异常的层次结构,这种方法将不起作用。
您可以将异常类放在您想要的任何地方,以便可以访问,但为每个类创建单独的文件是一种好方法。

于 2012-09-06T11:29:05.180 回答