编程风格的问题 - 重新审视 [英] A question of programming style - revisited

查看:68
本文介绍了编程风格的问题 - 重新审视的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为漫长的帖子道歉....

在以前的帖子中:
http://groups.google。 com / groups?hl = e ... dial.pipex.com


我问了一个关于如何确保某些整理的问题。代码将是

在方法结束时运行,与方法退出的位置无关。

的共识是使用try-finally块和使用块:在前一个
的情况下,我可以把我所有的整理 finally块中的代码和/或
try块中的其他所有内容。在简单处理的情况下,我可以在使用中初始化
。块。


虽然这大部分符合要求,但我遇到了两个问题:


1.在try块中放入大量代码没关系,其中任何返回

语句确实会导致finally块中的代码运行。

但是,try块的存在会导致任何代码通常

生成一个未处理的异常(总是有一些错误的代码,我已经写了!b $ b!)保持安静。一般来说,我喜欢只处理我选择的例外

。基本原理是任何其他类型的例外我都会知道并修复这个错误,它总是存在。因此,将大块代码包装到try块中似乎是不可能的。


2.当然,使用块只处理在using语句中初始化

的对象。然而,在Method存在之前我想要发生的事情的一个例子是写入TraceListener,例如

" Method is now exiting ...。


我认为有三种解决方案:

1.使用深层嵌套(即大量)if和switch语句和

简单地将整理放入并且通常会在最后跟踪代码。我不想这样,因为我最终得到了大量的嵌套代码。


2.在每个代码之前添加整理和跟踪代码返回声明,结尾也是

。这样可以保持嵌套,但确实会在方法中造成大量的重复




3.使用邪恶(ish)goto!也就是说,只需添加一个goto TidyUpStuff并将所有整理后的代码和跟踪代码放在TidyUpStuff标签之后,该标签在方法结束时将是

。我不是一个反goto Zealot,但是从基本的早期开始我就没有使用过

goto,如果我没有b / b
don没必要。


有什么想法吗?


干杯

马克

Apologies for the lengthy posting....
In a previous posting:
http://groups.google.com/groups?hl=e...dial.pipex.com

I asked a question about how to ensure that some "tidying up" code would be
run at the end of a Method independently of where the method exits. The
consensus was to use try-finally blocks and using blocks: In the former
case, I could put all my "tidying up" code in the finally block and
everything else in the try block. In the case of simply disposing, I could
initialise in a "using" block.

Whilst this mostly met the requirements, I ran into two issues:

1. Putting large amounts of code in the try block is OK and any return
statements therein do indeed cause the code in the finally block to run.
However, the presence of the try block causes any code that would normally
generate an unhandled exception (invariably some buggy code that I''ve
written!) to keep quiet. In general, I like to handle only the exceptions
that I choose. The rationale being that any other kind of exception I''d
rather know about and fix the bug, which it invariably is. So, wrapping up
great chunks of code into a try block seems to be out of the question.

2. Of course, the using block only disposes of objects that are initialised
in the using statement. However, an example of something I want to happen
just before the Method exists is writing to a TraceListener something like
"Method is now exiting...".

As I see it, there are three solutions:
1. Use deeply nested (i.e. large numbers of) if and switch statements and
simply put the "tidy up" and trace code at the end as one normally would. I
don''t like this because the I end up with huge amounst of nested code.

2. Add the tidy up and trace code before each return statement and also at
the end. This keeps the nesting down, but does cause a lot of repetion
within the method.

3. Use the evil(ish) goto! That is, simply add a goto TidyUpStuff and put
all the tidying up and trace code after the TidyUpStuff label which would be
at the end of the method. I''m not an anti-goto Zealot, but I haven''t used
goto since the early days of basic and would rather not revisit it if I
don''t have to.

Any thoughts?

Cheers
Mark


推荐答案

Mark,


见内联:


标记 <毫安** @ ReMoVeThIsBiTmossywell.com>在留言中写道

新闻:3f *********************** @ news.dial.pipex.com ...
Mark,

See inline:

"Mark" <ma**@ReMoVeThIsBiTmossywell.com> wrote in message
news:3f***********************@news.dial.pipex.com ...
为漫长的帖子道歉......
在以前的帖子中:
http://groups.google.com /groups?hl=e...dial.pipex.com
我问了一个关于如何确保某些整理的问题。代码将
在方法结束时运行,与方法退出的位置无关。
共识是使用try-finally块和使用块:在前一个
的情况下,我可以把我所有的整理。 finally块中的代码和try块中的其他所有内容。在简单处理的情况下,我可以在使用中初始化。虽然这大部分符合要求,但我遇到了两个问题:

1.在try块中放入大量代码是可以的,任何返回
其中的语句确实会导致finally块中的代码运行。
然而,try块的存在导致任何通常会生成未处理异常的代码(总是一些错误的代码,我''写完了!)保持安静。一般来说,我喜欢只处理我选择的例外情况。理由是任何其他类型的例外我都会非常了解和修复这个错误,它总是存在。因此,将大块代码包装到try块中似乎是不可能的。


这不一定是真的。以下语法完全可以接受:
可以接受:


尝试

{

//做点什么。

}

终于

{

//清理。

}


这会产生允许异常冒泡的效果,并且

仍然执行你的清理代码。如果你选择这样做,那么例外情况只会被吞噬。如果你需要捕获特定的异常,那么你可以使用

catch语句来做到这一点。另外,你可以在

其他try语句中嵌入try语句。

2.当然,using块只处理在使用中初始化
的对象声明。但是,在Method存在之前我想要发生的事情的一个例子是写入一个类似于
Method is now exiting ...的TraceListener。


这也不是真的。您可以执行以下操作:


//声明一次性的东西。

IDisposable pobjDisposable = new DisposableResource();


//在这里使用。

使用(pobjDisposable)

{

//使用pobjDisposable执行某些操作)。

}


这允许你初始化using语句之外的对象,

然后将它丢弃在using语句中。


鉴于这两点,它应该会给你一个很好的解决方案,这将使你能够避免下面列出的所有内容。


希望这会有所帮助。

-

- Nicholas Paldino [.NET / C#MVP]

- mv*@spam.guard.caspershouse.com

我认为有三种解决方案:
1.使用深层嵌套(即大量)if和switch语句和
简单地将整理放入并且通常会在最后跟踪代码。
我不喜欢这样,因为我最终得到了大量的嵌套代码。

2.在每个return语句之前添加整理和跟踪代码,并且在
结束。这样可以保持嵌套,但确实会在方法中造成大量的重复。

3.使用邪恶(ish)goto!也就是说,只需添加一个goto TidyUpStuff并在TidyUpStuff标签之后将所有整理和跟踪代码放在该方法的末尾,这将是
。我不是一个反goto Zealot,但是从基本的早期开始我就没有使用过
goto,如果我不需要的话,我宁愿不再重温它。

有什么想法吗?

欢呼
马克
Apologies for the lengthy posting....
In a previous posting:
http://groups.google.com/groups?hl=e...dial.pipex.com
I asked a question about how to ensure that some "tidying up" code would be run at the end of a Method independently of where the method exits. The
consensus was to use try-finally blocks and using blocks: In the former
case, I could put all my "tidying up" code in the finally block and
everything else in the try block. In the case of simply disposing, I could
initialise in a "using" block.

Whilst this mostly met the requirements, I ran into two issues:

1. Putting large amounts of code in the try block is OK and any return
statements therein do indeed cause the code in the finally block to run.
However, the presence of the try block causes any code that would normally
generate an unhandled exception (invariably some buggy code that I''ve
written!) to keep quiet. In general, I like to handle only the exceptions
that I choose. The rationale being that any other kind of exception I''d
rather know about and fix the bug, which it invariably is. So, wrapping up
great chunks of code into a try block seems to be out of the question.
This isn''t necessarily true. The following syntax is completely
acceptable:

try
{
// Do something.
}
finally
{
// Clean up.
}

This will have the effect of allowing the exception to bubble up, and
still execute your cleanup code. The exception only gets swallowed if you
choose to do so. If you need to catch specific exceptions, then you can use
catch statements to do that. Also, you can embed try statements within
other try statements.

2. Of course, the using block only disposes of objects that are initialised in the using statement. However, an example of something I want to happen
just before the Method exists is writing to a TraceListener something like
"Method is now exiting...".
This isn''t true either. You can do the following:

// Declare something that is disposable.
IDisposable pobjDisposable = new DisposableResource();

// Use it here.
using (pobjDisposable)
{
// Do something with pobjDisposable).
}

This allows you to initialize the object outside of the using statement,
then have it disposed of in a using statement.

Given these two points, it should give you a nice solution which will
allow you avoid everything that you outlined below.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

As I see it, there are three solutions:
1. Use deeply nested (i.e. large numbers of) if and switch statements and
simply put the "tidy up" and trace code at the end as one normally would. I don''t like this because the I end up with huge amounst of nested code.

2. Add the tidy up and trace code before each return statement and also at
the end. This keeps the nesting down, but does cause a lot of repetion
within the method.

3. Use the evil(ish) goto! That is, simply add a goto TidyUpStuff and put
all the tidying up and trace code after the TidyUpStuff label which would be at the end of the method. I''m not an anti-goto Zealot, but I haven''t used
goto since the early days of basic and would rather not revisit it if I
don''t have to.

Any thoughts?

Cheers
Mark



嗨Mark,
Hi Mark,
1.在try块中放入大量代码是可以的,其中任何返回
语句确实会导致finally块中的代码运行。
但是,try块的存在导致任何通常会产生未处理异常的代码(总是有一些我已经编写的错误代码!)来保持安静。一般来说,我喜欢只处理我选择的例外情况。理由是任何其他类型的例外我都会非常了解和修复这个错误,它总是存在。因此,将大块代码包装到try块中似乎是不可能的。


最后,块没有任何例外。也就是说,如果你因为异常而最终输入

块,那么异常将传递给调用者。
2.当然,using块只处理
的对象在using语句中初始化。但是,在Method存在之前我想要发生的事情的一个例子就是写入一个TraceListener类似于
Method is now exiting ...。
1. Putting large amounts of code in the try block is OK and any return
statements therein do indeed cause the code in the finally block to run.
However, the presence of the try block causes any code that would normally
generate an unhandled exception (invariably some buggy code that I''ve
written!) to keep quiet. In general, I like to handle only the exceptions
that I choose. The rationale being that any other kind of exception I''d
rather know about and fix the bug, which it invariably is. So, wrapping up
great chunks of code into a try block seems to be out of the question.
Finally blocks doesn''t catch any exceptions. That is if you enter finally
block because of exception the exception will be passed down to the caller.
2. Of course, the using block only disposes of objects that are initialised in the using statement. However, an example of something I want to happen
just before the Method exists is writing to a TraceListener something like
"Method is now exiting...".




实际上任何* using *语句都会生成try-finally块。所以,如果

尝试 - 终于不适合你*使用*也不行。


我什么也看不见任何问题,为什么不使用终于。也许你会抓住

例外并在调用链中的某个地方吃掉它们。

无论如何,如果你遇到异常,你将拥有你的终极块
$执行b $ b然后执行catch块。但是,如果您有未处理的异常,那么您将首先获得未处理异常的通知,然后执行

finally块。

你能发贴一些例子,其中一个finally块吞没未处理

例外吗?


B \ rgds

100



Actually any *using* statement generates try-finally block. So, if
try-finally doesn''t work for you *using* shouldn''t work as well.

I don''t see any problem why not to use "finally". Maybe you catch the
exceptions and eat them up somewhere down in the calling chain.
Anyways, if you catch an exception you will have your finally blocks
executed and then the catch block. If you have unhandled exception, though,
you will get first a notification for the unhandled exception and then the
finally blocks will be executed.

Can you post some example where a finally block swallows unhandled
exceptions?

B\rgds
100


" Mark" <毫安** @ ReMoVeThIsBiTmossywell.com>在留言中写道

新闻:3f *********************** @ news.dial.pipex.com ...
"Mark" <ma**@ReMoVeThIsBiTmossywell.com> wrote in message
news:3f***********************@news.dial.pipex.com ...
为漫长的帖子道歉......
在以前的帖子中:
http://groups.google.com /groups?hl=e...dial.pipex.com
我问了一个关于如何确保某些整理的问题。代码将
在方法结束时运行,与方法退出的位置无关。
共识是使用try-finally块和使用块:在前一个
的情况下,我可以把我所有的整理。 finally块中的代码和try块中的其他所有内容。在简单处理的情况下,我可以在使用中初始化。虽然这大部分符合要求,但我遇到了两个问题:

1.在try块中放入大量代码是可以的,任何返回
其中的语句确实会导致finally块中的代码运行。
然而,try块的存在导致任何通常会生成未处理异常的代码(总是一些错误的代码,我''写完了!)保持安静。一般来说,我喜欢只处理我选择的例外情况。理由是任何其他类型的例外我都会非常了解和修复这个错误,它总是存在。因此,将大块代码包装到try块中似乎是不可能的。


不是一个明智的想法。每条线都不太可能会失败,或者如果它们确实存在,你将能够捕获所有问题。这是明智的

只包装你认为可能会在尝试中爆炸的代码...抓住...

终于。


更好的选择是使用各种值进行单元测试。在

整数上尝试否定,以及零(非常重要,特别是除以零

条件)。然后使用调试工具来观察值。一般来说,

程序应该小而具体,可重用性。这也使得它们更容易测试和调试。

2.当然,using块只处理在using语句中初始化为
的对象。但是,在Method存在之前我想要发生的事情的一个例子是写入一个类似于
Method is now exiting ...的TraceListener。


有时候你必须明确地调用Dispose(),所以不要害怕

来跳过它。

正如我所看到的,有三种解决方案:
1.使用深层嵌套(即大量)if和switch语句,并简单地将整理放入并且通常会在最后跟踪代码。
我不喜欢这个,因为我最终得到了大量的嵌套代码。


在大多数情况下我不会选择这个。它最终得到了难以理解的

代码。例外情况是你在程序中有输入和输出检查。

ifs仍在那里,但不在一个大字符串中。

2.添加整理和跟踪每个return语句之前的代码以及最后的代码。这样可以保持嵌套,但确实会在方法中造成大量的重复。


这很好,但你通常应该在程序中有一个返回点,

喜欢:


尝试

{

//假设其他行动可能会爆炸


if(x = y)

returnString =" x = y" ;;

else

returnString =" x!= y";

}

终于

{

// DISPOSE

}


返回returnString;


虽然这个例子过于简单,但它只有一个返回点,

意味着你可以在最后一个中运行清理/>

3.使用邪恶(ish)goto!也就是说,只需添加一个goto TidyUpStuff并在TidyUpStuff标签之后将所有整理和跟踪代码放在该方法的末尾,这将是
。我不是一个反goto Zealot,但是从基本的早期开始我就没有使用
goto,如果我不需要的话,我宁愿不再重温它。
Apologies for the lengthy posting....
In a previous posting:
http://groups.google.com/groups?hl=e...dial.pipex.com
I asked a question about how to ensure that some "tidying up" code would be run at the end of a Method independently of where the method exits. The
consensus was to use try-finally blocks and using blocks: In the former
case, I could put all my "tidying up" code in the finally block and
everything else in the try block. In the case of simply disposing, I could
initialise in a "using" block.

Whilst this mostly met the requirements, I ran into two issues:

1. Putting large amounts of code in the try block is OK and any return
statements therein do indeed cause the code in the finally block to run.
However, the presence of the try block causes any code that would normally
generate an unhandled exception (invariably some buggy code that I''ve
written!) to keep quiet. In general, I like to handle only the exceptions
that I choose. The rationale being that any other kind of exception I''d
rather know about and fix the bug, which it invariably is. So, wrapping up
great chunks of code into a try block seems to be out of the question.
Not a wise idea. It is very unlikely that every line would possibly fail,
or, if they did, you would be able to catch all of the problems. It is wise
to only wrap code you feel is likely to blow up in a try ... catch ...
finally.

A better option is to unit test with a variety of values. Try negatives on
integers, as well as zeros (very important, esp. in divide by zero
conditions). Then using the debugging tools to watch values. In general,
procedures should be small and specific, for reusability. This also makes
them easier to test and debug.
2. Of course, the using block only disposes of objects that are initialised in the using statement. However, an example of something I want to happen
just before the Method exists is writing to a TraceListener something like
"Method is now exiting...".
There are times you have to explicitly call Dispose(), so do not be afraid
to leap on it.
As I see it, there are three solutions:
1. Use deeply nested (i.e. large numbers of) if and switch statements and
simply put the "tidy up" and trace code at the end as one normally would. I don''t like this because the I end up with huge amounst of nested code.
I would not opt for this in most situations. It ends up with unreadable
code. The exception is if you have input and output checks in a procedure.
The ifs are still there, but not in one large string.
2. Add the tidy up and trace code before each return statement and also at
the end. This keeps the nesting down, but does cause a lot of repetion
within the method.
This is fine, but you generally should have one return point in a procedure,
like:

try
{
// Assume other actions here that might "blow up"

if (x=y)
returnString = "x=y";
else
returnString = "x!=y";
}
finally
{
//DISPOSE
}

return returnString;

While this example is oversimplified, it has only one return point, which
means you can run clean up in one finally

3. Use the evil(ish) goto! That is, simply add a goto TidyUpStuff and put
all the tidying up and trace code after the TidyUpStuff label which would be at the end of the method. I''m not an anti-goto Zealot, but I haven''t used
goto since the early days of basic and would rather not revisit it if I
don''t have to.




不!没有!不!


好​​吧,可能有一个案例,但是goto通常意味着你没有想到

问题通过。


这是我的两分钱:


1.程序应该完成一个动作。如果你发现自己写了很长的程序,那么你可能会有一些可以分解的动作,

可能会被泛化然后重复使用。如果你发现你已经写了一个非常相似的代码块,那么你需要一个新的程序。


2.你应该检查输入如果值的全部范围不是可接受的,则值为b $ b。例如,如果你使用int类型并且只允许从1-1000开始使用int
,你应该捕获超出这个范围的值并抛出

异常。 />

3.考虑输出检查。这是一个模糊的地区。如果您知道输出

值只能在1-1000之间,那么您应该检查并记录范围之外的

(并且很可能抛出异常)。


4.只处理你需要清理的例外情况或b)你可以处理或b)你可以增加更多的清晰度。对于

渔民来说,捕获和释放是一个好主意,而不是开发人员。如果你发现错误,你应该有一个

方法,你可以解决至少一些错误(即错误说

目录不存在,所以我将创建目录并再次尝试)或

添加清晰度(除以零变为你不能为{变量

名称}输入0。


5.尝试... catch ...块不应该用于已知数量,或者

Paranoid编程非常昂贵。为什么要花一些时间来讨论
不会失败?例外是UI层,您希望阻止用户看到错误。
。在这个级别,您应该有某种形式的日志记录,以便在呼叫服务台时跟踪问题。

-

Gregory A Beamer

MVP; MCP:+ I,SE,SD,DBA


**************************** ********************** ********************

在盒子外面思考!

************************************* ************* ********************



No! No! No!

Okay, there might be a case, but goto generally means you have not thought
the problem through.

Here is my two cents:

1. Procedures should complete a single action. If you find yourself writing
really long procedures, you probably have actions that can be broken out,
possibly genericized and then reused. If you find that you have written a
very similar block of code, over and over, you need a new procedure.

2. You should check input values if the full range of values are not
acceptable. For example, if you are using an int type and only allow ints
from 1-1000, you should capture values outside of this range and throw an
exception.

3. Consider output checking. This is a fuzzier area. If you know the output
value can only be between 1-1000, you should check and log when it is
outside the range (and most likely throw an exception).

4. Only handle exceptions that you either a) need cleanup on or b) you can
handle or c) you can add more clarity. Catch and release is a great idea for
fishermen, not developers. If you catch an error, you should either have a
method where you can solve at least some of the errors (ie, the error says
directory does not exist, so I will create the directory and try again) or
add clarity (Divide by zero becomes "You cannot enter 0 for {variable
name}.")

5. Try ... catch ... blocks should not be used on known quantities, or
"Paranoid programming is very expensive". Why spend cycles on something that
will not fail? The exception is the UI layer, where you want to stop users
from seeing errors. At this level, you should have some form of logging to
track down problems when the help desk is called.
--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

************************************************** ********************
Think Outside the Box!
************************************************** ********************


这篇关于编程风格的问题 - 重新审视的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆