用户kokos通过使用关键字回答了c#的隐藏特性问题。你能详细说明一下吗?使用的用途是什么?


当前回答

Microsoft documentation states that using has a double function (https://msdn.microsoft.com/en-us/library/zhdeatwt.aspx), both as a directive and in statements. As a statement, as it was pointed out here in other answers, the keyword is basically syntactic sugar to determine a scope to dispose an IDisposable object. As a directive, it is routinely used to import namespaces and types. Also as a directive, you can create aliases for namespaces and types, as pointed out in the book "C# 5.0 In a Nutshell: The Definitive Guide" (http://www.amazon.com/5-0-Nutshell-The-Definitive-Reference-ebook/dp/B008E6I1K8), by Joseph and Ben Albahari. One example:

namespace HelloWorld
{
    using AppFunc = Func<IDictionary<DateTime, string>, List<string>>;
    public class Startup
    {
        public static AppFunc OrderEvents() 
        {
            AppFunc appFunc = (IDictionary<DateTime, string> events) =>
            {
                if ((events != null) && (events.Count > 0))
                {
                    List<string> result = events.OrderBy(ev => ev.Key)
                        .Select(ev => ev.Value)
                        .ToList();
                    return result;
                }
                throw new ArgumentException("Event dictionary is null or empty.");
            };
            return appFunc;
        }
    }
}

这是一种明智的做法,因为滥用这种做法会损害代码的清晰性。在DotNetPearls (http://www.dotnetperls.com/using-alias)中有一个关于c#别名的很好的解释,也提到了优点和缺点。

其他回答

Using as语句自动调用指定对象的dispose 对象。对象必须实现IDisposable接口。它是 可以在一条语句中使用多个对象,只要它们是 同类型的。

CLR将您的代码转换为CIL。using语句被转换成try和finally语句块。这就是using语句在CIL中的表示方式。使用语句可分为三个部分:获取、使用和处置。首先获取资源,然后使用包含finally子句的try语句。然后在finally子句中对对象进行处理。

总之,当您使用实现IDisposable类型的局部变量时,总是毫无例外地使用using1。

如果使用非局部IDisposable变量,则始终实现IDisposable模式。

两条简单的规则,无一例外。否则,防止资源泄漏是一件非常痛苦的事情。


1):唯一的例外是-当你处理异常时。在finally块中显式调用Dispose的代码可能会更少。

当您希望在使用某个资源后将其销毁时,将使用Using。

例如,如果您分配了一个File资源,并且只需要在一段代码中使用它进行少量的读写,使用有助于在完成后立即处理File资源。

所使用的资源需要实现IDisposable才能正常工作。

例子:

using (File file = new File (parameters))
{
    // Code to do stuff with the file
}

使用,在某种意义上

using (var foo = new Bar())
{
  Baz();
}

实际上是try/finally块的简写。它等价于代码:

var foo = new Bar();
try
{
  Baz();
}
finally
{
  foo.Dispose();
}

当然,您会注意到,第一个代码片段比第二个代码片段简洁得多,而且即使抛出异常,您也可能希望在清理过程中执行许多类型的操作。因此,我们提出了一个称为Scope的类,它允许您在Dispose方法中执行任意代码。例如,如果你有一个名为IsWorking的属性,你总是想在尝试执行一个操作后将其设置为false,你会这样做:

using (new Scope(() => IsWorking = false))
{
  IsWorking = true;
  MundaneYetDangerousWork();
}

你可以在这里阅读更多关于我们的解以及我们是如何推导它的。

对我来说,“using”这个名字有点令人困惑,因为它可以是一个导入Namespace的指令,也可以是一个用于错误处理的语句(就像这里讨论的那样)。

为错误处理取一个不同的名字会很好,而且可能是一个更明显的名字。