C# 一个using块,构造函数中有一个对象初始值设定项块
如果从using语句中调用构造函数,对象将自动释放,并用try/catch块将其包装。这是构造函数中的对象初始值设定项块 但是在同一语句中初始化的成员类型会怎么样呢?e、 g:C# 一个using块,构造函数中有一个对象初始值设定项块,c#,C#,如果从using语句中调用构造函数,对象将自动释放,并用try/catch块将其包装。这是构造函数中的对象初始值设定项块 但是在同一语句中初始化的成员类型会怎么样呢?e、 g: class TypeThatThrowsAnException { public TypeThatThrowsAnException() { throw new Exception(); } } using (SomeDisposabl
class TypeThatThrowsAnException
{
public TypeThatThrowsAnException()
{
throw new Exception();
}
}
using (SomeDisposable ds = new SomeDisposable() {
MemberThatThrowsAnException m = new TypeThatThrowsAnException()
})
{
// inside using statement
ds.doSomething();
}
当初始化某个一次性文件(即执行代码块)时,通过异常的成员抛出异常时,会发生什么情况
如果我们使用
块在范围之外调用这些成员构造函数,会有什么区别吗
class TypeThatThrowsAnException
{
public TypeThatThrowsAnException()
{
throw new Exception();
}
}
class SomeClass
{
public static TypeThatThrowsAnException StaticMember
{
get
{
return new TypeThatThrowsAnException();
}
}
}
using (SomeDisposable ds = new SomeDisposable() {
MemberThatThrowsAnException = SomeClass.StaticMember
})
{
// inside using statement
ds.doSomething();
}
在某些情况下,这可能是非常好和可读的,但我想知道是否有这样的警告或陷阱。或者说这是一个“一路禁止”。除此之外,您还需要记住可读性。对象初始值设定项在某种意义上是一个麻烦。。。但它们是一个可以避免问题的例子 在资源获取表达式正常完成之前,
using
语句不会“保护”对象。换句话说,您的代码如下所示:
SomeDisposable tmp = new SomeDisposable();
tmp.MemberThatThrowsAnException = new TypeThatThrowsAnException();
using (SomeDisposable ds = tmp)
{
// Stuff
}
更明显的问题是:)
当然,解决方案是使用语句在中指定属性:
using (SomeDisposable ds = new SomeDisposable())
{
MemberThatThrowsAnException = new TypeThatThrowsAnException();
// Stuff
}
现在,我们只依赖于SomeDisposable
的构造函数来清理它自己,如果它最终抛出异常,这是一个更合理的要求。从我所看到的,SomeDisposable类有一个类型为TypeThrowsanException的属性,当您实例化SomeDisposable时正在初始化-是吗
使用()-
SomeDisposable ds = null;
try
{
ds = new SomeDisposable();
}
finally
{
if (ds != null)
ds.Dispose();
}
因此,如果您的类型的构造函数抛出异常,控制将立即传递到finally块。在Ayende的博客上找到该主题。这是关于中使用语句的对象初始值设定项,但它似乎与您的问题有关。您的意思是使用一个using语句,然后使用一个单独的块吗?你的代码目前还不是很清楚。@Jon:我相信OP的意思是有一个using块,在constructor语句中有一个object initializer块。我也被这两对花括号弄糊涂了:P@Tomas当前位置是的,我以前没有把它计算好。我现在已经:)我现在已经知道可读性是这里的主要问题,然而……)@Caspar:看起来您正试图在对象初始值设定项中声明一个新变量(m
),这并没有帮助。当前发布的代码无法编译。不,这不是正确的翻译-因为在try块中有SomeDisposable
构造函数调用。不是。在试块之前。请参见C#4规范第8.13节。注意,谢谢Jon。顺便说一句,如果有人想要的话,这里就是——也许我错了,但是using语句是通过try/finally实现的,所以即使在构造时间(类型初始值设定项)之后抛出了一些异常,IDisposable.Dispose方法也将始终被调用。我错了吗?@Matias:它只有在资源获取成功后才进入try块,所以在这里没有帮助。请注意,我们谈论的是对象初始值设定项,而不是类型初始值设定项-非常不同的事情。我明白了,顺便说一句,这是一个lapsus:我谈论的是对象初始值设定项。对于第一个片段-如何处理tmp
?是否通过引用ds
来处理它?ds
也需要处理吗?@anatol:除非SomeDisposable
是一个结构,tmp
和ds
指的是同一个对象。不管该对象是如何处理的(即通过哪个变量),重要的是它是如何处理的。