C# 在没有单独的 try-catch 块的情况下尝试捕获每一行代码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/117173/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Try-catch every line of code without individual try-catch blocks
提问by tags2k
I do not currently have this issue, but you never know, and thought experiments are always fun.
我目前没有这个问题,但你永远不知道,思想实验总是很有趣。
Ignoring the obvious problems that you would have to have with your architecture to even be attempting this, let's assume that you had some horribly-written code of someone else's design, and you needed to do a bunch of wide and varied operations in the same code block, e.g.:
忽略你的体系结构必须有的明显问题,甚至尝试这个,让我们假设你有一些别人设计的可怕的代码,你需要在同一个代码中做一堆广泛多样的操作块,例如:
WidgetMaker.SetAlignment(57);
contactForm["Title"] = txtTitle.Text;
Casserole.Season(true, false);
((RecordKeeper)Session["CasseroleTracker"]).Seasoned = true;
Multiplied by a hundred. Some of these might work, others might go badly wrong. What you need is the C# equivalent of "on error resume next", otherwise you're going to end up copying and pasting try-catches around the many lines of code.
乘以一百。其中一些可能会奏效,而另一些可能会出错。您需要的是 C# 中“on error resume next”的等价物,否则您最终会在多行代码周围复制和粘贴 try-catch。
How would you attempt to tackle this problem?
您将如何尝试解决这个问题?
采纳答案by Mark Brackett
It's pretty obvious that you'd write the code in VB.NET, which actually does have On Error Resume Next, and export it in a DLL to C#. Anything else is just being a glutton for punishment.
很明显,您将在 VB.NET 中编写代码,它实际上确实具有On Error Resume Next,并将其在 DLL 中导出到 C#。其他任何事情都只是对惩罚的贪食。
回答by Orion Adrian
On Error Resume Next
is a really bad idea in the C# world. Nor would adding the equivalent to On Error Resume Next
actually help you. All it would do is leave you in a bad state which could cause more subtle errors, data loss and possibly data corruption.
On Error Resume Next
在 C# 世界中是一个非常糟糕的主意。添加等效项也不会On Error Resume Next
真正帮助您。它只会让您处于不良状态,这可能会导致更细微的错误、数据丢失和可能的数据损坏。
But to give the questioner his due, you could add a global handler and check the TargetSite to see which method borked. Then you could at least know what line it borked on. The next part would be to try and figure out how to set the "next statement" the same way the debugger does it. Hopefully your stack won't have unwound at this point or you can re-create it, but it's certainly worth a shot. However, given this approach the code would have to run in Debug mode every time so that you would have your debug symbols included.
但是为了让提问者得到应有的回报,您可以添加一个全局处理程序并检查 TargetSite 以查看哪个方法出错了。然后你至少可以知道它在哪条线上。下一部分将尝试找出如何以与调试器相同的方式设置“下一条语句”。希望此时您的筹码不会解开,或者您可以重新创建它,但这当然值得一试。但是,考虑到这种方法,代码每次都必须在调试模式下运行,以便包含调试符号。
回答by Guvante
Unfortunately you are probably out of luck. On Error Resume Next is a legacy option that is generally heavily discouraged, and does not have an equivalent to my knowledge in C#.
不幸的是,您可能不走运。On Error Resume Next 是一个传统选项,通常非常不鼓励它,并且没有与我在 C# 中的知识等效的选项。
I would recommend leaving the code in VB (It sounds like that was the source, given your specific request for OnError ResumeNext) and interfacing with or from a C# dll or exe that implements whatever new code you need. Then preform refactoring to cause the code to be safe, and convert this safe code to C# as you do this.
我建议将代码保留在 VB 中(这听起来像是源代码,考虑到您对 OnError ResumeNext 的特定请求)并与实现您需要的任何新代码的 C# dll 或 exe 接口或从 C# dll 或 exe 接口。然后执行重构以使代码安全,并在执行此操作时将此安全代码转换为 C#。
回答by Khoth
Rewrite the code. Try to find sets of statements which logically depend on each other, so that if one fails then the next ones make no sense, and hive them off into their own functions and put try-catches round them, if you want to ignore the result of that and continue.
重写代码。尝试找到逻辑上相互依赖的语句集,这样如果一个语句失败,那么下一个语句就没有意义了,如果你想忽略然后继续。
回答by mattlant
Hilite each line, one at a time, 'Surround with' try/catch. That avoids the copying pasting you mentioned
Hilite 每行,一次一个,“环绕”尝试/捕获。这避免了您提到的复制粘贴
回答by plinth
Refactor into individual, well-named methods:
重构为单独的、命名良好的方法:
AdjustFormWidgets();
SetContactTitle(txtTitle.Text);
SeasonCasserole();
Each of those is protected appropriately.
每一个都得到了适当的保护。
回答by Curt Hagenlocher
If you can get the compiler to give you an expression tree for this code, then you could modify that expression tree by replacing each statement with a new try-catch block that wraps the original statement. This isn't as far-fetched as it sounds; for LINQ, C# acquired the ability to capture lambda expressions as expression trees that can be manipulated in user code at runtime.
如果您可以让编译器为您提供此代码的表达式树,那么您可以通过用包装原始语句的新 try-catch 块替换每个语句来修改该表达式树。这并不像听起来那么牵强。对于 LINQ,C# 获得了将 lambda 表达式捕获为可以在运行时在用户代码中操作的表达式树的能力。
This approach is not possible today with .NET 3.5 -- if for no other reason than the lack of a "try" statement in System.Linq.Expressions. However, it may very well be viable in a future version of C# once the merge of the DLR and LINQ expression trees is complete.
这种方法今天在 .NET 3.5 中是不可能的——如果没有其他原因,除了 System.Linq.Expressions 中缺少“try”语句。但是,一旦 DLR 和 LINQ 表达式树的合并完成,它在 C# 的未来版本中很可能是可行的。
回答by tyshock
Ignoring all the reasons you'd want to avoid doing this.......
忽略你想避免这样做的所有原因......
If it were simply a need to keep # of lines down, you could try something like:
如果只是需要减少行数,您可以尝试以下操作:
int totalMethodCount = xxx; for(int counter = 0; counter < totalMethodCount; counter++) { try { if (counter == 0) WidgetMaker.SetAlignment(57); if (counter == 1) contactForm["Title"] = txtTitle.Text; if (counter == 2) Casserole.Season(true, false); if (counter == 3) ((RecordKeeper)Session["CasseroleTracker"]).Seasoned = true; } catch (Exception ex) { // log here } }
However, you'd have to keep an eye on variable scope if you try to reuse any of the results of the calls.
但是,如果您尝试重用调用的任何结果,则必须密切注意变量范围。
回答by Herms
This is one of the things that having a preprocessor is useful for. You could define a macro that swallows exceptions, then with a quick script add that macro to all lines.
这是拥有预处理器的有用之处之一。您可以定义一个包含异常的宏,然后使用快速脚本将该宏添加到所有行。
So, if this were C++, you could do something like this:
所以,如果这是 C++,你可以做这样的事情:
#define ATTEMPT(x) try { x; } catch (...) { }
// ...
ATTEMPT(WidgetMaker.SetAlignment(57));
ATTEMPT(contactForm["Title"] = txtTitle.Text);
ATTEMPT(Casserole.Season(true, false));
ATTEMPT(((RecordKeeper)Session["CasseroleTracker"]).Seasoned = true);
Unfortunately, not many languages seem to include a preprocessor like C/C++ did.
不幸的是,似乎没有多少语言像 C/C++ 那样包含预处理器。
You could create your own preprocessor and add it as a pre-build step. If you felt like completely automating it you could probably write a preprocessor that would take the actual code file and add the try/catch stuff in on its own (so you don't have to add those ATTEMPT() blocks to the code manually). Making sure it only modified the lines it's supposed to could be difficult though (have to skip variable declarations, loop constructs, etc to that you don't break the build).
您可以创建自己的预处理器并将其添加为预构建步骤。如果您想完全自动化它,您可能会编写一个预处理器,该预处理器将获取实际代码文件并自行添加 try/catch 内容(因此您不必手动将那些 ATTEMPT() 块添加到代码中) . 确保它只修改它应该修改的行可能很困难(必须跳过变量声明、循环构造等,以免破坏构建)。
However, I think these are horrible ideas and should never be done, but the question was asked. :)
但是,我认为这些是可怕的想法,永远不应该这样做,但是有人提出了这个问题。:)
Really, you shouldn't ever do this. You need to find what's causing the error and fix it. Swallowing/ignoring errors is a bad thing to do, so I think the correctanswer here is "Fix the bug, don't ignore it!". :)
真的,你永远不应该这样做。您需要找出导致错误的原因并修复它。吞下/忽略错误是一件坏事,所以我认为这里的正确答案是“修复错误,不要忽视它!”。:)
回答by JB King
You could look at integrating the Enterprise Library's Exception Handling component for one idea of how to handle unhandled exceptions.
您可以查看集成企业库的异常处理组件,以了解如何处理未处理的异常。
If this is for ASP.Net applications, there is a function in the Global.asax called, "Application_Error" that gets called in most cases with catastrophic failure being the other case usually.
如果这是针对 ASP.Net 应用程序,则 Global.asax 中有一个名为“Application_Error”的函数,在大多数情况下会被调用,灾难性故障通常是另一种情况。
回答by CodeRedick
You coulduse goto, but it's still messy.
你可以使用 goto,但它仍然很乱。
I've actually wanted a sort of single statement try-catch for a while. It would be helpful in certain cases, like adding logging code or something that you don't want to interrupt the main program flow if it fails.
我实际上想要一种单一的语句 try-catch 有一段时间了。在某些情况下它会很有帮助,比如添加日志代码或一些你不想在主程序流失败时中断的东西。
I suspect something could be done with some of the features associated with linq, but don't really have time to look into it at the moment. If you could just find a way to wrap a statement as an anonymous function, then use another one to call that within a try-catch block it would work... but not sure if that's possible just yet.
我怀疑某些与 linq 相关的功能可以做些什么,但目前没有时间研究它。如果您能找到一种方法将语句包装为匿名函数,然后使用另一种方法在 try-catch 块中调用它,它会起作用……但不确定这是否可行。