让我们说我想做一些自定义异常。而且我想要更多。我可以为每个新的异常创建一个新类,但还有另一种方法吗?如果我必须创建一个新的类,在哪里存储它们?它只是在项目的根文件夹中看起来不那么好。
[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) { }
}
}
等等。我是否真的必须创建始终一个新类并粘贴相同的代码?有什么建议吗?
答案 0 :(得分:8)
我可以为每个新的异常创建一个新类,但还有另一种方法吗?
不,没有别的办法。如果要创建新的异常类型,则需要一个新的类。
在哪里存放它们?
在所有需要使用它们的代码都可访问的位置。
如果有些异常相同,我在做什么,只是异常的名称有所改变?
是的,仍然需要创建一个新类 - 尽管可以从现有的异常类派生新的类。
答案 1 :(得分:1)
通常情况下,对于类似这样的事情,我会创建一个单独的项目或名称空间,以便在整个项目/解决方案中使用所有这些自定义异常(甚至枚举)。
这给我一个参考点/汇编参考。
除了关于具有相同“外观”的异常的问题之外,我还将创建一个基类,可以通过“略有不同”的名称继承其他异常。
答案 2 :(得分:1)
每次都必须创建新的异常,因为这就是catch()在try ... catch块中的工作方式,以捕获特定的异常类型。但我真的很喜欢CLR通过C#book采取的下一步方法:
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(); }
}
现在可以为这样的异常创建新的args:
public class ExceptionAExceptionArgs : ExceptionArgs
{
//may add some properties if required here
}
并抓住这样的“新例外”:
try
{
//do something here...
}
catch (Exception<ExceptionAExceptionArgs> ex)
{
}
我会让你编写更少的代码来创建新的异常。
请注意:如果您希望创建一个例外情况,那么这种方法将无效,其中有一个基本异常类和少数子类异常。
您可以将异常类放在您想要的位置,以便可以访问,但是为每个类创建单独的文件是一种很好的方法。