我试图了解我将如何在我的代码中使用Throw。我有一个MainForm类来处理Windows窗体GUI,然后我有Manager类来读取和保存文件中的数据。
我在两个课程中都使用了Try / Catch,但是我的教练希望我在Manager课程中使用Throw,尽管我正在阅读它,但我不明白它会做什么? Will Throw会影响MainForm类中的Try / Catch吗?
如果捕获了异常,我还在manager类中使用了一个消息框,但是根据教师的说法,不允许在管理器中使用消息框,那么我该怎么办呢?我可以只在MainForm类中使用消息框吗?帮助理解和扩展我的知识!谢谢!
MainForm类:
try
{
motelManager.SaveToFile(file);
}
catch
{
MessageBox.Show("Ett fel uppstod!", "Varning!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
经理班:
public void SaveToFile(string filePath)
{
try
{
string newFilePath = filePath.Replace(".bin", "");
filestream = new FileStream(newFilePath + ".bin", FileMode.Create);
BinaryFormatter b = new BinaryFormatter();
b.Serialize(filestream, animals);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "Varning!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
if (filestream != null) filestream.Close();
}
答案 0 :(得分:6)
你的经理班应该是这样的:
public void SaveToFile(string filePath)
{
try
{
string newFilePath = filePath.Replace(".bin", "");
filestream = new FileStream(newFilePath + ".bin", FileMode.Create);
BinaryFormatter b = new BinaryFormatter();
b.Serialize(filestream, animals);
}
catch(Exception ex)
{
if (filestream != null) filestream.Close();
throw;
// but don't use
// throw ex;
// it throws everything same
// except for the stacktrace
}
// or do it like this
//catch(Exception ex)
//{
// throw;
// but don't use
// throw ex;
// it throws everything same
// except for the stacktrace
//}
//finally
//{
// if (filestream != null) filestream.Close();
//}
}
并在您的主要班级中:
try
{
motelManager.SaveToFile(file);
}
catch (Exception e)
{
MessageBox.Show("Ett fel uppstod!", "Varning!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
答案 1 :(得分:1)
public void SaveToFile(string filePath)
{
try
{
string newFilePath = filePath.Replace(".bin", "");
filestream = new FileStream(newFilePath + ".bin", FileMode.Create);
BinaryFormatter b = new BinaryFormatter();
b.Serialize(filestream, animals);
}
catch (Exception ex)
{
if (filestream != null) filestream.Close();
//what you want
//MessageBox.Show(ex.Message, "Warning!");
throw (new Exception("Your custom message"));
}
}
在你的经理中:
try
{
manager.SaveToFile(filePath);
}
catch (Exception ex)
{
// here shows your 'Your custom message'
MessageBox.Show(ex.Message);
}
答案 2 :(得分:1)
您可以使用Application ThreadException来捕获任何异常。而且你的保存逻辑包括使用而不是try catch,在这种情况下它会关闭你的流。
public void SaveToFile(string filePath)
{
string newFilePath = filePath.Replace(".bin", "");
using(var filestream = new FileStream(newFilePath + ".bin", FileMode.Create))
{
BinaryFormatter b = new BinaryFormatter();
b.Serialize(filestream, animals);
}
}
在入口点(static void main())订阅此事件。
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
Application.ThreadException += Application_ThreadException;
}
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
MessageBox.Show(".......");
}
答案 3 :(得分:1)
抛出只会将异常引发到调用函数。 (在这种情况下,无论谁调用SaveToFile)。如果那里有一个错误处理程序,它将被捕获,否则它将继续向上调用堆栈,直到它被捕获或处于顶层。
答案 4 :(得分:1)
最好在表单中向用户呈现异常 - 只是因为在较大的结构良好的系统中,Manager对象可能与GUI没有任何连接。
一般规则是捕获后端[Manager]类中的异常以清除任何资源(即关闭文件),然后从异常处理程序中重新抛出异常,如下所示:
public void SaveToFile(string filePath)
{
try
{
string newFilePath = filePath.Replace(".bin", "");
filestream = new FileStream(newFilePath + ".bin", FileMode.Create);
BinaryFormatter b = new BinaryFormatter();
b.Serialize(filestream, animals);
}
catch(Exception ex)
{
/*
* cleanup resources and rethrow the exception for catching and handling elsewhere
*/
if (filestream != null)
filestream.Close();
throw;
}
}
答案 5 :(得分:1)
在具有多个层的应用程序中,基础层中发生的异常不会发送到更高层或调用应用程序。
例如,如果数据库相关代码出现问题,则不会将其发送到客户端应用程序或更高层。这样做的原因是为用户提供友好的错误消息。比如,在删除操作期间您有外键引用错误,您可以:
上面的层可能会将此异常包装到另一个更高级别的消息,然后将其抛出。这类似于你被要求做的事情。
在Manager类的代码中,检查可能发生的异常数。如果您使用的是VS,则工具提示/帮助文本会提供该信息。如果您不使用VS,请查看MSDN以获取此信息。
在表单中,处理管理器层可以抛出的所有异常,如果发生严重错误,也可以处理一般异常。恕我直言,这就是你的经理层代码应该如何
try
{
string newFilePath = filePath.Replace(".bin", "");
FileStream filestream = new FileStream(newFilePath + ".bin", FileMode.Create);
BinaryFormatter b = new BinaryFormatter();
b.Serialize(filestream, animals);
}
catch (ArgumentNullException argNullException)
{
// Log current exception
// Wrap it under your exception type
CustomWrapException customWrap = new CustomWrapException();
customWrap.Message = "Your custom message here.";
customWrap.InnerException = argNullException;
throw customWrap;
}
catch (SecurityException securityException)
{
// Log current exception
// Replace current exception with you custom exception
CustomReplaceException replaceException = new CustomReplaceException();
replaceException.Message = "Your custom message here.";
throw replaceException;
}
finally
{
// Close stream and dispose objects here
}
您的表单应该像这样进行异常处理:
try
{
// Call mananger code from here
}
catch (CustomWrapException wrapException)
{
// replace/wrap if desired
// Display message to user
}
catch (CustomReplaceException replaceException)
{
// replace/wrap if desired
// Display message to user
}
catch (Exception exception)
{
// This is for everything else that may go wrong apart from known possible exceptions
// Display message to user
}
finally
{
}
HTH。
答案 6 :(得分:0)
就像这样......
try { }
catch(Exception e)
{ throw }
当它抛出异常时,它将改变源和堆栈跟踪,以便从包含该try-catch块的方法的那一行抛出e看起来已经从该方法抛出异常。