变量声明后的括号

时间:2014-10-16 13:49:21

标签: c# .net

我不熟悉以下语法,我想知道变量在退出大括号后会发生什么:

public string method(int projectid)
{
    string result = string.empty;
    var service = _service;
    {
         result = service.dosomething(); //_service implements it's own Dispose
    }

    result += "we are going to do some further operations like sum a large list that"
    result += "might take a non-trivial amount of time."

    return result;
}

紧跟在_service: { /* etc */ }后面的括号是否表示服务变量仅在.dosomething()方法的范围内,之后在执行result +=块指示的X操作时 - 表示垃圾收集器可以收集服务并将垃圾收集起来吗?

基本上,我想知道围绕var result = service.dosomething()的括号是什么告诉编译器要对service_service做什么。

7 个答案:

答案 0 :(得分:7)

它对service_service无效。

我的猜测(基于评论)是这段代码看起来像

public string method(int projectid)
{
    string result = string.empty;
    using (var service = _service)
    {
         result = service.dosomething();
    }

    result += "we are going to do some further operations like sum a large list that"
    result += "might take a non-trivial amount of time."

    return result;
}

并且有人发现该对象在使用后通过_service被使用,并通过删除using并添加分号和评论说明为什么{{1}来“修复”该错误并没有放在这里,把大括号留作旧马车版本的无用痕迹。


注意:为了公平对待编码器,也许最初是service,有人决定重用服务实例,将代码转换为上面提到的错误版本,然后演变成当前版本。

答案 1 :(得分:6)

变量result{ }中是本地的。因此,您无法在service之外访问它。

您的代码甚至无法编译,因为您尝试为尚未声明的变量赋值。

<强>更新

正如我可以通过您的帖子理解的那样,您可能希望使用using语句来使用名为service的一次性对象,并询问引擎盖下会发生什么。

最初,你想要的就像下面这样做:

using(var service = new ...)
{
    result = service.dosomething();
}

...中,您将放置服务类的类型。

如果这样做,那么这段代码将由C#编译器编译为以下代码

try
{
    ServiceType service = new ServiceType;
    result = service.dosomething(); 
}
finally
{
    if (service != null)
    ((IDisposable)service).Dispose();
}

我已将<{em>名称ServiceType提供给...以便编写上述示例。 因此,您应该在那里放置正确的类型。

正如您现在看到的,using语句是用于调用您的Disposable对象的Dispose方法的语法糖。正如在MSDN中更全面和正式地阐述的那样

  

通常,当您使用IDisposable对象时,您应该声明和   在using语句中实例化它。 using语句调用   以正确的方式在对象上处理方法,以及(当您使用它时)   如前所示)它也会导致对象本身超出范围   只要调用Dispose。在使用块中,对象是   只读且无法修改或重新分配。使用声明   确保 即使在您时发生异常,也会调用Dispose   正在调用对象上的方法。你可以通过实现相同的结果   将对象放在try块中,然后在a中调用Dispose   最后阻止; 实际上,这就是翻译using语句的方式   由编译器。前面的代码示例扩展为以下内容   编译时的代码(注意额外的花括号来创建   对象的范围有限)

答案 2 :(得分:3)

与...相同:

public string method(int projectid)
{
    string result = string.empty;
    var service = _service;
    //{
         result = service.dosomething(); //_service implements it's own Dispose
    //}

    result += "we are going to do some further operations like sum a large list that"
    result += "might take a non-trivial amount of time."

    return result;
}

答案 3 :(得分:1)

will print "barbaz"

public static void Main()
{
    string foo = "bar";

    // new scope
    {
        foo += "baz";
    }

    Console.WriteLine(foo);
}

由于在父作用域中声明了foo,因此可以在子作用域中访问它。

答案 4 :(得分:1)

括号表示范围。当程序执行通过end}括号时,其中的任何变量都会超出范围。

现在,如果该变量是对对象实例的 only 引用,那么是的,它就有资格进行垃圾回收。然而,当执行下一个garbace集合运行时是不确定的。

在这种情况下,_service变量仍然保存对实例的引用。所以什么都不会被垃圾收集。

垃圾收集永远不会调用Dispose。它必须直接从代码调用或使用using语句调用。如果存在,GC将调用终结器,以关闭任何非托管资源。

答案 5 :(得分:0)

每当你声明一个可变的内部{}括号时,它只能在这个括号内查看和访问。 如果您想访问var,则必须在方法中声明var result;并在括号result = service.dosomething();

中初始化它

如果您以这种方式使用它,您将能够使用它。

答案 6 :(得分:0)

您指的是大括号或花括号。括号是方形的东西。

大括号建立一个新的本地范围。在此范围内定义的变量是范围的本地变量。

具有析构函数的局部变量将在离开块时执行该析构函数。

使用当前编写的代码,这些都不会发生。