一个using块,在构造函数中有一个对象初始化块

Cas*_*jne 5 c#

如果从using语句中调用构造函数,则会自动处理该对象,并使用try/catch块对其进行包装.这是构造函数中的对象初始化程序块.

但是在同一语句中初始化的成员类型会变成什么?例如:

  class TypeThatThrowsAnException 
  {
       public TypeThatThrowsAnException() 
       {
           throw new Exception();
       }
  }

  using (SomeDisposable ds = new SomeDisposable() {
       MemberThatThrowsAnException m = new TypeThatThrowsAnException()
  })
  {
       // inside using statement
       ds.doSomething();
  }
Run Code Online (Sandbox Code Playgroud)

以会发生什么MemberThatThrowsAnException时,它抛出时SomeDisposable被初始化,即,被执行的代码块中的例外呢?

如果我们将那些成员构造函数调用到块的范围之外,它会有什么不同using吗?

  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();
  }
Run Code Online (Sandbox Code Playgroud)

在某些情况下,这可能是非常好的和可读的,但我想知道是否有这样的任何警告或陷阱.或者说这是一直禁止的.除此之外,您还需要牢记可读性.

Jon*_*eet 5

对象初始化是在一些感觉这里的红鲱鱼......但他们是哪里的问题是可以避免的一个例子。

using在资源获取表达式正常完成之前,该对象不会被语句“保护” 。换句话说,你的代码是这样的:

SomeDisposable tmp = new SomeDisposable();
tmp.MemberThatThrowsAnException = new TypeThatThrowsAnException();

using (SomeDisposable ds = tmp)
{
    // Stuff
}
Run Code Online (Sandbox Code Playgroud)

这显然有问题:)

当然,解决办法是财产分配using语句:

using (SomeDisposable ds = new SomeDisposable())
{
    MemberThatThrowsAnException = new TypeThatThrowsAnException();
    // Stuff
}
Run Code Online (Sandbox Code Playgroud)

现在,如果最终抛出异常,我们只依赖于的构造函数SomeDisposable在其自身之后进行清理——这是一个更合理的要求。