【问题标题】:Unexpected behavior when "using" is used使用“使用”时的意外行为
【发布时间】:2012-07-21 16:59:30
【问题描述】:

我可以使用用户定义的类型,比如使用 block 里面的类吗?我用的时候:

  1. 上面说,我需要继承IDisposable并实现Dispose方法。我继承并尝试定义 Dispose 方法,但我做不到。它向我展示了它不是公开的或其他东西:(请用一段关于如何实现它的小代码帮助我理解这一点。

  2. 1234563在使用之外?我认为没有充分的理由:(我的推理是否正确?但我可以使用相同的变量在 using 之外实例化另一个类(可以这样做吗?因为我没有看到编译错误),尽管我很清楚我们应该练习编码指南(但从概念上讲,我正在寻求逻辑)......

请帮忙,我是 C# 新手

【问题讨论】:

  • +1 WRT 到第 2 点,有一群人(包括我)不同意 C# 的有限词汇范围。这可能永远不会改变。
  • 你的标题所指的“奇怪”行为到底是什么?
  • @JonSkeet:抱歉,我可能需要更正我的标题,真的不确定如何更正标题……抱歉使用“奇怪”这个词。
  • @Divine:点击帖子上的“编辑”按钮
  • @JonSkeet:谢谢你,做到了:)

标签: c# asp.net .net


【解决方案1】:

using 语句的全部意义在于调用IDisposable 接口中指定的Dispose 方法。

是的,在实现接口时,要么方法需要公开,要么您需要使用显式接口实现:

// Via a public method
public class Foo : IDisposable
{
    public void Dispose()
    {
        // Stuff
    }
}

// Via explicit interface implementation
public class Bar : IDisposable
{
    void IDisposable.Dispose()
    {
        // Stuff
    }
}

这里没有关于IDisposable 的具体内容——它只是普通的接口实现。

你不应该仅仅为了它而实现IDisposable - 想法是它应该为你清理 - 如果你没有任何清理要执行,你不需要using 声明。

至于第二点:您根本不允许声明与仍在范围内的另一个局部变量同名的局部变量。阅读起来会非常混乱,因此被禁止。来自 C# 规范的第 8.5.1 节:

在局部变量声明中声明的局部变量的范围是声明发生的块。在局部变量的局部变量声明符之前的文本位置引用局部变量是错误的。在局部变量的范围内,声明另一个同名的局部变量或常量是编译时错误。

请注意,您可以在一种方法中仍然有两次相同的局部变量名称,前提是它们不能同时在范围内:

void M()
{
    using (Stream x = ...)
    {
    }

    using (Stream x = ...)
    {
    }

    for (int x = 0; x < 10; x++)
    {
    }

    // Block introduced just for scoping...
    {
        string x = "";
        ...
    }
}

【讨论】:

  • 非常感谢乔恩·斯基特。好吧,您的第一点现在没有给我任何编译错误,太好了。但是我想知道或不明白,我应该如何实现与使用此“使用”进行sql连接时类似的内置清理过程,最后我调用了methodname.Dispose()。意思是,我知道 SQL 类在该内置中给出了一些实现?如果我不编写代码进行清洁,我不能使用相同的东西吗?在这种情况下,我最好使用用户定义的类...?
  • @Divine:完全不清楚你的意思。 using 语句绝对等同于在 finally 块中调用 Dispose - 除了它更易于阅读和维护。我不知道您正在编写的类型是否甚至需要任何清理代码......但如果需要,您需要自己编写。不清楚您在谈论哪个 SQL 类,但如果它是实现 IDisposable 的东西,它将包含适当的代码来清理其资源。
  • 另外,就第二点而言,我现在使用相同的变量来实例化另一个类,它给了我错误:(嗯,我完全理解你所说的编码指南和可读性的观点,但我试图理解,使用范围中的变量仅在 { 和 } 之间,对吗?意思是,我不能在使用范围之外使用该变量,即使我使用,它也会给我异常?对吗?为什么我不能使用相同的变量至少为不同的类实例命名?:(
  • @Divine:它不会给你一个异常,它会给你一个编译时错误。例外情况非常不同。您不能使用相同的变量名,因为这会令人困惑——该语言试图保护您免受自己的伤害。当你有一个局部变量和一个实例变量调用相同的东西时,这已经够糟糕了——同时在范围内有两个同名的局部变量会更糟。
  • 您好 Jon,非常感谢您提供的详细的变量使用方式。但我试图理解的变量范围是 using(Class c = new Class()) { }; // 这里,c 的作用域只在里面 using right ?那为什么我不能重用派生 c = new derived(); ?????
猜你喜欢
  • 2013-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-02
  • 2013-10-06
  • 1970-01-01
  • 2017-10-16
相关资源
最近更新 更多