考虑以下来源:
static void Main(string[] args)
{
bool test;
Action lambda = () => { test = true; };
lambda();
if (test)
Console.WriteLine("Ok.");
}
它应该编译,对吧?好吧,事实并非如此。我的问题是:根据 C# 标准,这段代码应该编译还是编译器错误?
Use of unassigned local variable 'test'
注意:我知道,如何修复错误,我部分知道,为什么会发生。然而,局部变量是无条件赋值的,我想编译器应该注意到这一点,但它没有。我想知道,为什么。
答案评论:C# 允许声明未分配的变量,这实际上非常有用,即。
bool cond1, cond2;
if (someConditions)
{
cond1 = someOtherConditions1;
cond2 = someOtherConditions2;
}
else
{
cond1 = someOtherConditions3;
cond2 = someOtherConditions4;
}
编译器正确编译了这段代码,我认为,不分配变量实际上会使代码好一点,因为:
边缘: 这更有趣。考虑 C++ 中的相同示例:
int main(int argc, char * argv[])
{
bool test;
/* Comment or un-comment this block
auto lambda = [&]() { test = true; };
lambda();
*/
if (test)
printf("Ok.");
return 0;
}
如果您注释掉该 block ,编译将以警告结束:
main.cpp(12): warning C4700: uninitialized local variable 'test' used
但是,如果您删除注释,编译器将不会发出任何警告。在我看来,它能够确定是否最终设置了变量。
最佳答案
My question is: according to C# standard, should this code compile or is this a compiler bug?
这不是错误。
C# Language Specification 的第 5.3.3.29 节(4.0) 概述了关于匿名函数的明确赋值规则,包括 lambda 表达式。我会在这里发布。
5.3.3.29 Anonymous functions
For a lambda-expression or anonymous-method-expression expr with a body (either block or expression) body:
The definite assignment state of an outer variable v before body is the same as the state of v before expr. That is, definite assignment state of outer variables is inherited from the context of the anonymous function.
The definite assignment state of an outer variable v after expr is the same as the state of v before expr.
The example
delegate bool Filter(int i); void F() { int max; // Error, max is not definitely assigned Filter f = (int n) => n < max; max = 5; DoWork(f); }generates a compile-time error since max is not definitely assigned where the anonymous function is declared. The example
delegate void D(); void F() { int n; D d = () => { n = 1; }; d(); // Error, n is not definitely assigned Console.WriteLine(n); }also generates a compile-time error since the assignment to n in the anonymous function has no affect on the definite assignment state of n outside the anonymous function.
您可以看到这如何适用于您的具体示例。变量 test 没有在 lambda 表达式声明之前专门赋值。在执行 lambda 表达式之前,它不会被专门分配。并且在lambda表达式执行完成后并没有具体赋值。按照规则,编译器不会认为变量在 if 语句中被读取时已明确赋值。
至于为什么,我只能重复我读过的关于此事的内容,并且只能重复我记得的内容,因为我无法生成链接,但 C# 不会尝试这样做,因为尽管这是一个微不足道的案例,但眼睛可以看到,这种类型的分析往往是非常重要的,而且实际上可以解决停机问题。因此,C#“保持简单”并要求您按照更容易适用和可解决的规则进行游戏。
关于c# - Lambda 分配局部变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14224190/
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
通过rubykoans.com,我在about_array_assignment.rb中遇到了这两段代码你怎么知道第一个是非并行赋值,第二个是一个变量的并行赋值?在我看来,除了命名差异之外,代码几乎完全相同。4deftest_non_parallel_assignment5names=["John","Smith"]6assert_equal["John","Smith"],names7end45deftest_parallel_assignment_with_one_variable46first_name,=["John","Smith"]47assert_equal'John
我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是
我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我早就知道Ruby中的“常量”(即大写的变量名)不是真正常量。与其他编程语言一样,对对象的引用是唯一存储在变量/常量中的东西。(侧边栏:Ruby确实具有“卡住”引用对象不被修改的功能,据我所知,许多其他语言都没有提供这种功能。)所以这是我的问题:当您将一个值重新分配给常量时,您会收到如下警告:>>FOO='bar'=>"bar">>FOO='baz'(irb):2:warning:alreadyinitializedconstantFOO=>"baz"有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会发生重新分配。 最佳答案
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
我收到格式为的回复#我需要将其转换为哈希值(针对活跃商家)。目前我正在遍历变量并执行此操作:response.instance_variables.eachdo|r|my_hash.merge!(r.to_s.delete("@").intern=>response.instance_eval(r.to_s.delete("@")))end这有效,它将生成{:first="charlie",:last=>"kelly"},但它似乎有点hacky和不稳定。有更好的方法吗?编辑:我刚刚意识到我可以使用instance_variable_get作为该等式的第二部分,但这仍然是主要问题。
我正在编写一个简单的静态Rack应用程序。查看下面的config.ru代码:useRack::Static,:urls=>["/elements","/img","/pages","/users","/css","/js"],:root=>"archive"map'/'dorunProc.new{|env|[200,{'Content-Type'=>'text/html','Cache-Control'=>'public,max-age=6400'},File.open('archive/splash.html',File::RDONLY)]}endmap'/pages/search.
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.