我不熟悉以下语法,我想知道变量在退出大括号后会发生什么:
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
做什么。
答案 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)
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)
您指的是大括号或花括号。括号是方形的东西。
大括号建立一个新的本地范围。在此范围内定义的变量是范围的本地变量。
具有析构函数的局部变量将在离开块时执行该析构函数。
使用当前编写的代码,这些都不会发生。