有条件的使用块 [英] Conditional using block
问题描述
我想听听您对条件using
块的意见.问题是我需要具有如下结构:
Hi,
I''d like to hear your opinions on conditional using
blocks. The thing is that I need to have a structure like the following:
public void AMethod(bool useClass2) {
using (Class1 variable1 = new Class1()) {
using (Class2 variable2 = new Class2(variable1) {
using (Class3 variable3 = new Class3(variable2) {
variable3.DoSomething();
}
}
}
}
现在的问题是,根据方法的参数,应该包括或排除中间的using块.如果参数useClass2
为true
,则应按上述方式执行代码,但如果参数为false
,则执行应如下所示:
Now the problem is that based on the parameters of the method the middle using block should either be included or excluded. If the parameter useClass2
is true
, the code should be executed as above but if the parameter is false
, then the execution should look like the following:
public void AMethod(bool useClass2) {
using (Class1 variable1 = new Class1()) {
using (Class3 variable3 = new Class3(variable1) {
variable3.DoSomething();
}
}
}
因此,根据参数,可以包括中间的using块,而最里面的using块则使用Class1或Class2.
现在,可以使用例如:
- 单独的专门方法(不需要参数)
- 对Class2使用If..Else结构,并在必要的部分上复制内部代码等.
- Separate, specialized methods (no need for parameter)
- using If..Else structure for the Class2, and duplicating the inner code on necessary parts etc.
So based on the parameter, the middle using block may be included and the innermost using block uses either Class1 or Class2.
Now, this could be done with for example:
推荐答案
分开的方法是要走的路.至少,这些方法的名称可以使发生的事情更加明显.或者,即使不需要使用Class2也不会造成重大损失,只需使用第一个即可.
I think separate methods is the way to go. At the very least, the names of those methods could make it more obvious what''s going on. Or, if there''s no significant penalty to using Class2 even when it''s not needed, just use the first.
非常有趣的问题,但是的,您缺少了一些东西.
您的代码示例可能具有不同的含义.查看构造函数Class2.Class2
.它可能意味着:
基于类型为Class1
的 late绑定的单个构造函数:
Very interesting question, but yes, you are missing something.
Your code sample may mean the different things. Look at the constructorClass2.Class2
. It may mean:
Single constructor based on late binding of the typeClass1
:
class Class1 : IDisposable {/* ... */}
class Class2 : IDisposable {
internal Class2(Class1 variable) {/* ... */}
//...
}
// which is based on this inheritance:
class Class2 : Class1, IDisposable {/* ... */}
相同的代码片段可以在不同的内容中实现,而类Class1
和Class2
是不相关的:
The same code fragments could be implemented in different content, where the classes Class1
and Class2
are unrelated:
class Class2 {
internal Class2(Class1 variable) {/* ... */}
internal Class2(Class2 variable) {/* ... */}
//...
}
您开始了解它了吗?如果使用多态,则可以优化代码并避免使用"if":
Are you starting to get it? If you use polymorphism, you can optimize your code and avoid "if":
static void AMethod(bool useClass2) {
using (Class1 variable1 = new Class1()) {
Class1 factoryParameter = null;
if (useClass2)
factoryParameter = variable1;
using (Class1 variable2 = Class1Factory(factoryParameter)) {
using (Class3 variable3 = new Class3(variable2)) {
variable3.DoSomething();
} //variable3 is disposed here
} //variable2 is disposed here
} //variable1 is disposed here
} //AMethod
static Class1 Class1Factory(Class1 factoryParameter) { // important: late-bound return type
if (factoryParameter == null)
return new Class1();
else
return new Class2(factoryParameter);
} //Class1Factory
当那些IDisposable
类/结构不相关时,在更一般的情况下该怎么办?您可以将幼稚"的实现留给单独的实现,将两个示例与一个"if"运算符放在一起,但是如果您具有更高的嵌套级别(这很容易是这种情况),那么看起来就太混乱了.
还有另一种做事的方式.首先,using
语句等效于某些try-finally块(或嵌套块).您可以从字面上使用它;它比using
更为紧凑,因为try-finally更通用.但是,您也可以使用众所周知的特殊技术:
创建一个特殊的"DisposalAccumulator
"类,该类可以累积要放置在某个容器中的所有实例.此类还应实现IDisposable
,以便在单个using
语句中使用.在using
下仅创建具有此类嵌套的此类的实例.您需要进一步解释吗?我想你应该有个主意.如果不是,那么欢迎您提出后续问题-很高兴能处理正确提出的合理问题.
我认为这里最重要的标准是避免重复代码.我想你明白.请参阅:
http://en.wikipedia.org/wiki/Don%27t_repeat_yourself [DisposalAccumulator",因为它可能对其他读者有帮助.
我最大的祝福,
What to do in the more general case, when those IDisposable
classes/structures are unrelated? You can leave your "naive" separate implementation putting both samples together with one "if" operator, but it could look too much messed up if you have greater level of nesting (which easily can be the case).
There is another way of doing thing. First, the using
statement is equivalent to some try-finally block (or nested blocks). You can literally use it; it can be more compact then using
, because try-finally is more general. But you can also use the special and well known technique:
Create a special "DisposalAccumulator
" class which can accumulate all instances to be disposed in some container. This class should also implement IDisposable
, to be used in one single using
statement. Create only the instance of such class under using
with only one level of nesting. Do you need to explain you more? I thing you should get an idea. If not just yes, your follow-up questions are very welcome — it''s always a pleasure to deal with correctly formulated and sensible questions.
I think most important criterion here would be to avoid any repeated code. I think you understand it. Please see:
http://en.wikipedia.org/wiki/Don%27t_repeat_yourself[^].
Hold on, I''ll try to provide code samples for those two general-case solutions: try-finally and "DisposalAccumulator
", because it may be of some value to other readers.
My very best wishes,
我通过 ^ ],但我确定您也希望看到我的解决方案.
您实际上可以为using
语句变量分配空值. using块的语法糖实际上是在处理之前在finally块中检查空变量.因此,以Sergey的示例为例,我提供了以下解决方案,该解决方案减少了冗余代码,并且不需要其他类:
I landed here via the article[^] proposed by Sergey, but I''m sure you''d like to see my solution as well.
You can actually assign null values tousing
statement variables. The syntactic sugar for the using block actually checks for a null variable in the finally block prior to a dispose. So, per Sergey''s example, I provided the following solution that reduces redundant code and doesn''t require the need for an additional class:
static void NotSoNaiveWay(bool createSecond)
{
using (First first = new First())
using (Second second = (createSecond) ? new Second(first) : null)
using (Third third = (createSecond) ? new Third(second) : new Third(first))
{
third.DoSomething();
}
}
如果您使Third
类处理所有提供的IDisposable
元素,则可以将其进一步简化为:
If you made the Third
class dispose of any provided IDisposable
elements, you could simplify this further to:
static void NotSoNaiveWay(bool createSecond)
{
using (First first = new First())
using (Third third = (createSecond) ? new Third(new Second(first)) : new Third(first))
{
third.DoSomething();
}
}
希望对您有所帮助.
I hope that helps.
这篇关于有条件的使用块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!