我应该如何处理 using 块中的空对象?

发布于 2024-12-05 16:44:54 字数 358 浏览 1 评论 0原文

鉴于这样的情况:

using (var foo = CreateFoo()) {
    if (foo != null) {
        // do stuff
    }
}

我想避免嵌套的 if。遗憾的是,明显的解决方案是不可能的,因为 Break 不适用于 using:

using (var foo = CreateFoo()) {
    if (foo == null) {
        break;
    }
    // do stuff
}

是否有一种模式仍然可以避免由 if != null 引起的额外缩进?

Given a situation like this:

using (var foo = CreateFoo()) {
    if (foo != null) {
        // do stuff
    }
}

I would like to avoid the nested if. Sadly, the obvious solution is not possible because break does not work with using:

using (var foo = CreateFoo()) {
    if (foo == null) {
        break;
    }
    // do stuff
}

Is there a pattern to still avoid the additional indentation caused by the if != null?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

信仰 2024-12-12 16:44:54

如果您对从 CreateFoo() 返回的类有足够的控制,您可以实现一个 空对象 并返回此值而不是实际的 NULL 值

If you have sufficient control over the class returned from CreateFoo() you could just implement a Null Object and return this instead of the actual NULL value

寄居人 2024-12-12 16:44:54

我喜欢命名明确的小方法:

public void DoWhatEver()
{
   using (var foo = CreateFoo())
   {
     if (foo == null) return;

     //DoWhatEver
   }
}

I favor small clearly named methods:

public void DoWhatEver()
{
   using (var foo = CreateFoo())
   {
     if (foo == null) return;

     //DoWhatEver
   }
}
君勿笑 2024-12-12 16:44:54

引入一个采用 lambda 的辅助方法。所以你的代码变成:

UsingIfNotNull(CreateFoo(), foo => {
  //do stuff
});

其中有你想要的缩进。 UsingIfNotNull 的定义是:

public static void UsingIfNotNull<T>(T item, Action<T> action) where T : class, IDisposable {
  if(item!=null) {
    using(item) {
      action(item);
    }
  }
}

Introduce a helper method that takes a lambda. So your code becomes:

UsingIfNotNull(CreateFoo(), foo => {
  //do stuff
});

which has the indentation you want. The definition of UsingIfNotNull is:

public static void UsingIfNotNull<T>(T item, Action<T> action) where T : class, IDisposable {
  if(item!=null) {
    using(item) {
      action(item);
    }
  }
}
半衾梦 2024-12-12 16:44:54

这只是一个风格问题......代码很好。您真的那么担心缩进吗?无论如何,这是另一种丢失缩进的方法......

public void DoWhatEver()
{
   using(var foo = CreateFoo())
   {
       DoStuffWithFoo(foo);
   }

}

private void DoStuffWithFoo(Foo foo)
{
    if(foo == null) return;

    //DoWhatEver

}

This is just a style issue ... code is fine. Are you really that worried about indents? Here's another way to lose the indents anyway ...

public void DoWhatEver()
{
   using(var foo = CreateFoo())
   {
       DoStuffWithFoo(foo);
   }

}

private void DoStuffWithFoo(Foo foo)
{
    if(foo == null) return;

    //DoWhatEver

}
久夏青 2024-12-12 16:44:54

在这种一般意义上,我相信我会将 using 包装在 try...catch 块中,并在对象为 null 时抛出异常,但这是个人偏好。

In that sort of generic sense, I believe I would wrap the using in a try...catch block and throw an exception if the object was null, but that's a personal preference.

安人多梦 2024-12-12 16:44:54

就我个人而言,我可能会保留您发布的代码。

然而,既然你问了(并且冒着让自己对这个经常被诟病的语言功能投反对票的风险),你总是可以使用“goto”:

using (var foo = CreateFoo()) {
    if (foo == null) {
        goto SkipUsingBlock;
    }
    // do stuff
}

SkipUsingBlock:
// the rest of the code...

Personally I would probably leave the code as you've posted it.

However, since you asked (and at the risk of exposing myself to downvotes to this often-maligned language feature), you could always use "goto":

using (var foo = CreateFoo()) {
    if (foo == null) {
        goto SkipUsingBlock;
    }
    // do stuff
}

SkipUsingBlock:
// the rest of the code...
_畞蕅 2024-12-12 16:44:54

这是一个丑陋的黑客,但它避免了额外的标识:(

do using (var foo = CreateFoo()) {
    if (foo == null) {
        break;
    }
    // do stuff
} while (false);

不,我不建议这样做。这只是一个概念证明,表明它是可能的。)

如果可能,我建议重构您的代码反而:

 using (var foo = CreateFoo()) {
    if (foo != null) {
        doSomethingWith(foo);  // only one line highly indented
    }
}

It's an ugly hack, but it avoids the additional identation:

do using (var foo = CreateFoo()) {
    if (foo == null) {
        break;
    }
    // do stuff
} while (false);

(No, I don't recommend to do this. This is just a proof-of-concept to show that it's possible.)

If possible, I would suggest to refactor your code instead:

 using (var foo = CreateFoo()) {
    if (foo != null) {
        doSomethingWith(foo);  // only one line highly indented
    }
}
爱已欠费 2024-12-12 16:44:54

C# 编译器将 using(var foo = CreateFoo()) 语句视为:

try
{
var foo = CreateFoo();
}
finally
{
  ((IDisposable) foo).Dispose();
}

如果您的方法 CreateFoo 返回的不是一次性对象 - 根本不要使用 using。在其他情况下你可以写:

try
{
var foo = CreateFoo();
//do stuff like foo.SomeMethod (if foo == null exception will be thrown and stuff will not be done)
}
finally
{
  ((IDisposable) foo).Dispose();
}

C# compiler treats using(var foo = CreateFoo()) statement in:

try
{
var foo = CreateFoo();
}
finally
{
  ((IDisposable) foo).Dispose();
}

If your method CreateFoo return not disposable object - do not use using at all. In other case you can write:

try
{
var foo = CreateFoo();
//do stuff like foo.SomeMethod (if foo == null exception will be thrown and stuff will not be done)
}
finally
{
  ((IDisposable) foo).Dispose();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文