一个同事维护delphi代码的时候发现原来 的软件内有很多with。过多的with让代码难以调试。
引入with的本意在于节省重复出现的对象名。比如说,如果有这样的调用:
Function foo ()
begin
ObjectA.Prop1 = "a";
ObjectA.Prop2 ="b";
ObjectA.Run();
end
那么可以采用with让代码显得简洁:
With ObjectA do
Begin
Prop1 ="a";
Prop2 = "b";
Run();
End;
在这样的情况下,使用With无可厚非。因为这样的代码确实简洁,并且并不影响代码的可读性。
问题是有些with用的太过头了。最典型的是with嵌套with,并且一个with内有多个Property和Method的调用,很难看出那个属性是哪个对象的。这样就使用的过度了。
和delphi不同,在c#内根本就不支持with。和with类似的using也只是为了dispose的目的,而不是为了代码更加简洁。那么在c#内,遇到类似的代码要如何做呢?
其实上面的例子代码内,隐隐的躲藏着一个设计问题:就是代码的分工并不合理。代码的全部工作由函数Foo和ObjectA来承担。在foo内大量的引用对象ObjectA,这是一种职责不清晰的迹象:说明Foo做了很多本来属于ObjectA的工作。
如果把这些工作分配有ObjectA来完成,那么代码应该是这样的:
Class A
Foo()
Begin
Prop1 ="a";
Prop2 = "b";
Run();
end
而调用方foo这样:
Function foo()
begin
ObjectA.Foo()
end
自然的,既然所有的代码调用都在ClassA内部发生,那么本来天经地义应该使用with的场合,就在职责清晰的过程中,自然的变得并无必要了。
with并非绝对不可应用,也不是所有的代码都必须清晰职责,只要不影响阅读和使用,代码质量并不下降的情况下,with也是可以用的。