C#“使用”块

发布于 2024-10-14 01:16:08 字数 594 浏览 8 评论 0原文

我有类似下面的代码...这里有人提到 WebClient、Stream 和 StreamReader 对象都可以从使用块中受益。两个简单的问题:

1:这个小片段在使用块时会是什么样子?我自己做研究没有问题,所以资源链接很好,但只看一个例子会更快更容易,我会从中理解它。

2:我想养成良好的编码标准的习惯,如果我了解一点使用块更好的原因会有所帮助......这只是为了让你不必担心关闭还是在那里还有更多理由吗?谢谢!

WebClient client = new WebClient();
Stream stream = client.OpenRead(originGetterURL);
StreamReader reader = new StreamReader(stream);

JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine());
string encryptionKey = (string)jObject["key"];
string originURL = (string)jObject["origin_url"];

stream.Close()
reader.Close()

I've got something like the code below...someone here mentioned that the WebClient, Stream, and StreamReader objects could all benefit from using blocks. Two easy questions:

1: How would this little snippet look with using blocks? I've no problem with doing my own research so resource links are fine but it'd be quicker and easier to just see an example and I'll understand it from that.

2: I'd like to get in the habit of good coding standards, would help if I knew a little about the reasons why using blocks are better...is it just so you don't have to worry about closing or are there more reasons? Thanks!

WebClient client = new WebClient();
Stream stream = client.OpenRead(originGetterURL);
StreamReader reader = new StreamReader(stream);

JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine());
string encryptionKey = (string)jObject["key"];
string originURL = (string)jObject["origin_url"];

stream.Close()
reader.Close()

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

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

发布评论

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

评论(9

日久见人心 2024-10-21 01:16:08
using (WebClient client = new WebClient())
{
    // do work
}

提供方便的语法,确保正确使用IDisposable 对象。

来自 MSDN:using 语句(C# 参考)


通常,当您使用 IDisposable 对象时,您应该在 using 语句中声明并实例化它。 using 语句以正确的方式调用对象上的 Dispose 方法,并且它还一旦调用 Dispose,就会导致对象本身超出范围。在 using 块内,对象是只读的,不能修改或重新分配。


using 语句确保即使在调用对象的方法时发生异常,也会调用 Dispose。 您可以通过将对象放入 try 块中然后调用 Dispose 来实现相同的结果在finally块中;事实上,这就是编译器翻译 using 语句的方式。

using (WebClient client = new WebClient())
{
    // do work
}

Provides a convenient syntax that ensures the correct use of IDisposable objects.

From MSDN: using Statement (C# Reference)


As a rule, when you use an IDisposable object, you should declare and instantiate it in a using statement. The using statement calls the Dispose method on the object in the correct way, and it also causes the object itself to go out of scope as soon as Dispose is called. Within the using block, the object is read-only and cannot be modified or reassigned.


The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; in fact, this is how the using statement is translated by the compiler.

悟红尘 2024-10-21 01:16:08
using (var client = new WebClient())
using (var stream = client.OpenRead(originGetterURL))
using (var reader = new StreamReader(stream))
{
    var jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine());
    var encryptionKey = (string)jObject["key"];
    var originURL = (string)jObject["origin_url"];
}

或者简单地:

using (var client = new WebClient())
{
    var json = client.DownloadString(originGetterURL);
    var jObject = Newtonsoft.Json.Linq.JObject.Parse(json);
    var encryptionKey = (string)jObject["key"];
    var originURL = (string)jObject["origin_url"];
}
using (var client = new WebClient())
using (var stream = client.OpenRead(originGetterURL))
using (var reader = new StreamReader(stream))
{
    var jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine());
    var encryptionKey = (string)jObject["key"];
    var originURL = (string)jObject["origin_url"];
}

or simply:

using (var client = new WebClient())
{
    var json = client.DownloadString(originGetterURL);
    var jObject = Newtonsoft.Json.Linq.JObject.Parse(json);
    var encryptionKey = (string)jObject["key"];
    var originURL = (string)jObject["origin_url"];
}
时光礼记 2024-10-21 01:16:08
using(WebClient client = new WebClient()) {

}

与使用相同

WebClient client;
try {
    client = new WebClient();
} finally {
    if(client != null) {
        client.Dispose();
    }
}

更容易使用

using(WebClient client = new WebClient()) {

}

is the same as

WebClient client;
try {
    client = new WebClient();
} finally {
    if(client != null) {
        client.Dispose();
    }
}

A lot easier to use using

半世蒼涼 2024-10-21 01:16:08

它很简单:

使用 *using* 本身并不是“良好实践”,而是一种处理您应该处理的对象的简短方法(语法糖)。诸如文件、数据库连接以及网络之类的东西。

您可以这样做:

using(WebClient we = new WebClient))
{
//do something with 'we' here
}

这基本上只是正常使用变量 we 的快捷方式,然后调用 we.Dispose() 进行清理。

语法:

using (<Any class that Implements IDisposable>)
{
//use the class
}

您应该看到的其他 SO 问题:
using 关键字和 IDisposable 接口之间有什么关系?
在 using 语句中使用各种类型 (C#)

Its simple :

Using *using* is not "good practice" as such, more a short way (syntactic sugar) of disposing objects that you should be disposing. Things like Files, Connections to a Database and in your case a network.

You would do something like:

using(WebClient we = new WebClient))
{
//do something with 'we' here
}

This is basically just a shortcut for using the variable we normally and then calling we.Dispose() which does a clean up.

Syntax :

using (<Any class that Implements IDisposable>)
{
//use the class
}

Other SO questions you should see:
What is the relationship between the using keyword and the IDisposable interface?
using various types in a using statement (C#)

臻嫒无言 2024-10-21 01:16:08

像这样的事情:

using(WebClient client = new WebClient())
using(Stream stream = client.OpenRead(originGetterURL))
StreamReader reader = new StreamReader(stream) {
  JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine());
  string encryptionKey = (string)jObject["key"];
  string originURL = (string)jObject["origin_url"];
}

至于为什么 using 块很好,并且比手动调用 Dispose... 更好,如果该 using 块中的任何代码在您之前抛出异常到达关闭所有内容的那一行?您实际上会泄漏 IDisposable 对象在幕后管理的任何非托管资源。 using 确保 Dispose 被正确调用,即使面对异常(本质上是通过注入适当的 try/finally 块)。

如果可能(即,您不必跨范围保留某些 IDisposable 的生命周期),您应该利用 using 块(如果没有其他原因,只是它们减少了您必须编写的样板代码量)以确保您自己的代码安全正确。

Something like this:

using(WebClient client = new WebClient())
using(Stream stream = client.OpenRead(originGetterURL))
StreamReader reader = new StreamReader(stream) {
  JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine());
  string encryptionKey = (string)jObject["key"];
  string originURL = (string)jObject["origin_url"];
}

As for why using blocks are good, and better than manually calling Dispose... image if any of the code in that using block threw an exception before you hit the lines where you close everything? You'd essentially leak whatever unmanaged resource the IDisposable object is managing under the hood. using ensures that Dispose is called correctly, even in the face of an exception (by essentially injecting the appropriate try/finally block).

When possible (i.e., you don't have to preserve the lifetime of some IDisposable across scopes), you should leverage using blocks if for no other reason than they reduce the amount of boilerplate code you have to write in order to ensure your own code is safe and correct.

大海や 2024-10-21 01:16:08

使用 {} 块只需在右大括号处调用 Dispose(),或者更确切地说,告诉垃圾收集器它可以处置该对象。你会这样使用它:

using (WebClient client = new WebClient())
{
    Stream stream = client.OpenRead(originGetterURL); StreamReader reader = new  StreamReader(stream);

    JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine()); string encryptionKey = (string)jObject["key"]; string originURL = (string)jObject["origin_url"];

    stream.Close() reader.Close()
} // 'client' instance gets disposed here

using {} blocks simply call Dispose() at the closing brace--or rather, tell the Garbage Collector that it can dispose of the object. You'd use it like:

using (WebClient client = new WebClient())
{
    Stream stream = client.OpenRead(originGetterURL); StreamReader reader = new  StreamReader(stream);

    JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine()); string encryptionKey = (string)jObject["key"]; string originURL = (string)jObject["origin_url"];

    stream.Close() reader.Close()
} // 'client' instance gets disposed here
陌上青苔 2024-10-21 01:16:08

@Darin 的答案显示了代码。它们好的原因是,使用块会导致编译器吐出代码,在退出块之前自动对对象调用“Dispose”(使其立即释放可能正在使用的任何资源) - 即使抛出异常在块内

@Darin's answer shows the code. The reason they are good is that using blocks cause the compiler to spit out code that will automatically call "Dispose" on the object (to have it immediately release any resources it may be using) before exiting the block - even if an exception gets thrown within with the block

海之角 2024-10-21 01:16:08

using 相当于 try..finally,因此即使块内抛出异常,处理程序也会运行。

using is equivalent to try.. finally so the disposer will run even if an exception is thrown within the block.

春花秋月 2024-10-21 01:16:08

使用块有两个原因:

  • 它们看起来不错
  • 块内的代码通常可能会引发异常。所以你需要 try-finally

最后, using-block 例如

using (Somthing somthing=...)
{
    DoActions(somthing);
}

与以下构造相同:

{Somthing somthing=...
    try
    {
        DoActions(somthing);
    }
    finally
    {
        somthing.Dispose();
    }
}//the outer bracket limits the variable

There are 2 reasons for using-blocks:

  • They look good
  • The code inside the block often could throw exceptions. So you wold need try-finally

In the end a using-block e.g.

using (Somthing somthing=...)
{
    DoActions(somthing);
}

is identical to the followin contstruct:

{Somthing somthing=...
    try
    {
        DoActions(somthing);
    }
    finally
    {
        somthing.Dispose();
    }
}//the outer bracket limits the variable
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文