C# 难读try..catch..finally块的格式设置?
如何格式化try..catch.finally块?特别是当只围绕少量代码进行包装时,它会破坏一切,使代码在我看来非常不可读和难看 例如:C# 难读try..catch..finally块的格式设置?,c#,formatting,try-catch-finally,C#,Formatting,Try Catch Finally,如何格式化try..catch.finally块?特别是当只围绕少量代码进行包装时,它会破坏一切,使代码在我看来非常不可读和难看 例如: 这7行代码变成了16行的混乱 有没有关于更好地尝试..捕获..最终格式化的建议?空白。作为最低要求,我总是在每个return语句之前以及代码的“doing stuff”和“creating variables”部分之间加上一行空格 try { MyService service = new Service(); service.DoS
这7行代码变成了16行的混乱
有没有关于更好地尝试..捕获..最终格式化的建议?空白。作为最低要求,我总是在每个return语句之前以及代码的“doing stuff”和“creating variables”部分之间加上一行空格
try
{
MyService service = new Service();
service.DoSomething();
return something;
}
catch (Exception ex)
{
LogSomething();
return somethingElse;
}
finally
{
MarkAsComplete();
service.Dispose();
}
好多了。嗯,我想那很好。这其中的一部分进入了花括号位置的辩论。您可以这样做:
try {
//
} catch(Exception ex) {
//
} finally {
//
}
不过我更喜欢你的。但是,您可能需要考虑修改代码只有一个返回语句。我发现这是一个更好的设计。我在同一行用括号格式化代码:
try {
MyService service = new Service();
service.DoSomething();
return something;
} catch (Exception ex) {
LogSomething();
return somethingElse;
} finally {
MarkAsComplete();
service.Dispose();
}
如果我想要更多的间距,我更喜欢添加空行。这也可以作为代码逻辑块之间的分隔符。事实上,这对我来说非常好。如果您的实际代码看起来很像这样,那么我真的不会担心它。现在发生的事情很清楚
如果你的实际代码比较复杂,那么考虑把这些块分解成好名字的方法。
我认为你的格式也读得很好。我的建议是尽量少用catch
语句。只有当你真的需要抓东西的时候才使用它。否则,您可以让程序的其他部分处理异常。整个“早期失败”的概念
就我个人而言,我倾向于在代码中遵循前面的风格。。。它提供了发表评论的空间,并更好地展示了我的逻辑流程 我有一个宽屏,我把它的一边,所以空白允许各种列排列好,不会伤害我太多,因为我有这么多的屏幕房地产,因为它是
try { // getting a service
MyService service = new Service();
service.DoSomething();
return something;
}
catch (Exception ex) { // the fact that a service might be full/timedout
LogSomething();
return somethingElse;
}
finally { // remove any resources the service may still hold.
MarkAsComplete();
service.Dispose();
}
你可以考虑容器(非常聪明的工厂)和建议(处理所有混乱的细节) 在代码中,您可能会看到:
//a class that knows how to take care of the messy infrastructure details
public class MyMessyInterceptor : IInterceptor {
public void Intercept(IInvocation invocation) {
//handle the messy details of continuing with the method-invocation,
//but within a try-catch-finally that includes exception handling and
//call logging.
}
}
//a function that will configure a container (very smart factory)
public IContainer CreateContainer() {
var builder = new ContainerBuilder();
//tell the container-builder about the interceptor
builder
.Register(c => new MyMessyInterceptor())
.Named("keep-my-code-clean")
;
//tell the container what to do when you ask it for a ISomething
builder
.Register<SomethingImpl>()
.As<ISomething>()
.InterceptedBy("keep-my-code-clean")
;
return builder.BuildContainer();
}
//some function out there in your code somewhere that needs to make a
//service call; there's hundreds of functions out there just like this
//in your code, and they all just got much simpler
public object GottaGoDoSomething() {
//find the container
var container = GetTheSingletonContainerObject();
//ask for an instance of ISomething - it knows to provide a
//SomethingImpl wrapped in an interceptor that takes care of all
//the logging and exception handling
var something = container.resolve<ISomething>();
//call the big method
return something.DoSomething();
//magically (not really), the exception handling and logging are
//already taken care of
}
//一个知道如何处理混乱的基础结构细节的类
公共类MyMessyInterceptor:IInterceptor{
公共无效拦截(IInvocation调用){
//处理继续方法调用的混乱细节,
//但在一个包含异常处理和
//呼叫记录。
}
}
//配置容器的函数(非常智能的工厂)
公共IContainer CreateContainer(){
var builder=new ContainerBuilder();
//告诉容器生成器有关拦截器的信息
建设者
.Register(c=>newmymessynterceptor())
.Named(“保持我的代码干净”)
;
//告诉容器当你向它要东西时该怎么做
建设者
.Register()
.As()
.InterceptBy(“保持我的代码干净”)
;
返回builder.BuildContainer();
}
//在代码中的某个地方有一些函数需要
//服务呼叫;像这样的函数有数百种
//在你的代码中,它们都变得简单多了
公共对象gottagodoothing(){
//找到容器
var container=GetTheSingletonContainerObject();
//询问ISomething的一个实例-它知道提供一个
//一些被包装在拦截器中的MPL,可以处理所有
//日志记录和异常处理
var something=container.resolve();
//称之为大方法
归还某物;
//神奇的是(不是真的),异常处理和日志记录
//已经照顾好了
}
拦截器类只出现一次。注册每个拦截器和服务类也只发生一次。设置容器(非常智能的工厂)当然很复杂
然而,代码中每一个必须使用服务对象的地方,以及必须将服务对象的使用嵌入复杂而混乱的基础结构细节(如异常处理和日志记录)中的地方,都变得非常干净和简单。只有一个CreateContainer
,但是有数百个GottaGoDoSomething
s,所以这非常简单,但代价是有点复杂
(注意:代码示例使用Autofac容器框架和Castle拦截器框架。我知道这是服务位置模式的示例,不是依赖注入模式,但重点是说明拦截器并将其注册到容器中,而不是说明依赖注入。)I,就像你原来拥有的一样。.cs文件中的物理行不会花费任何费用,也不会更改最终的输出代码。因此,请使用您所需要的一切,以便为您或您的团队提供最佳的可读性 事实上,在编写代码时,您应该尝试使用比这里显示的16行更多的行,为自己或他人添加注释 加入
// a comment that says what's going on
通常,您可以更好地提醒自己这一尝试是什么。当您在6个月后返回时,Catch应该做什么。您可以使用
using
块而不是显式的Dispose()
,否则您可能必须在处理它之前检查null,而using
块可以帮您做到这一点。不幸的是,它确实增加了嵌套=/
try
{
using(MyService service = new MyService())
{
service.DoSomething();
return something;
}
}
catch (SpecificException ex)
{
LogSomething(ex);
return somethingElse;
}
finally
{
MarkAsComplete();
}
我总是尝试重构我所有的try-catch块,并用它们自己的方法封装它们
这似乎总是让一切都更具可读性,另外,让方法只做一件事是一种很好的编程实践。如果您在try-catch-finally语句的上下都有代码,那么很可能您做的不止一件事。如果您真的想摆脱强制的格式,但格式很难看(是的,我同意:p) 选择面向方面的编程,你最终会得到一个“尝试” 嵌入
//a class that knows how to take care of the messy infrastructure details
public class MyMessyInterceptor : IInterceptor {
public void Intercept(IInvocation invocation) {
//handle the messy details of continuing with the method-invocation,
//but within a try-catch-finally that includes exception handling and
//call logging.
}
}
//a function that will configure a container (very smart factory)
public IContainer CreateContainer() {
var builder = new ContainerBuilder();
//tell the container-builder about the interceptor
builder
.Register(c => new MyMessyInterceptor())
.Named("keep-my-code-clean")
;
//tell the container what to do when you ask it for a ISomething
builder
.Register<SomethingImpl>()
.As<ISomething>()
.InterceptedBy("keep-my-code-clean")
;
return builder.BuildContainer();
}
//some function out there in your code somewhere that needs to make a
//service call; there's hundreds of functions out there just like this
//in your code, and they all just got much simpler
public object GottaGoDoSomething() {
//find the container
var container = GetTheSingletonContainerObject();
//ask for an instance of ISomething - it knows to provide a
//SomethingImpl wrapped in an interceptor that takes care of all
//the logging and exception handling
var something = container.resolve<ISomething>();
//call the big method
return something.DoSomething();
//magically (not really), the exception handling and logging are
//already taken care of
}
// a comment that says what's going on
try
{
using(MyService service = new MyService())
{
service.DoSomething();
return something;
}
}
catch (SpecificException ex)
{
LogSomething(ex);
return somethingElse;
}
finally
{
MarkAsComplete();
}