为什么C#没有像C这样的局部静态变量?我想念!!
因为他们搞砸了,并且遗漏了一个适合自己的有用功能.
关于你应该如何编码以及什么是聪明的,你应该重新考虑你的生活方式的所有争论都是浮夸的防御借口.
当然,C#是纯粹的,而且是以人为本的.这就是他们为lambda函数自动生成持久本地的原因.这一切都很复杂.我觉得很蠢.
在许多情况下,循环范围静态是有用且重要的.
简短而真实的答案是,您必须将本地静态移动到类范围内,并在C#中使用类命名空间污染.把你的投诉带到市政厅.
状态通常是对象的一部分或类型的一部分,而不是方法的一部分.(当然,例外是捕获变量.)
如果你想要一个本地静态变量的等价物,要么创建一个实例变量,要么创建一个静态变量 - 并考虑该方法本身是否应该实际上是该状态的不同类型的一部分.
MSDN博客文章为什么C#不支持静态方法变量?处理原帖中提出的确切问题:
C#没有此功能有两个原因.
首先,通过使用类级静态可以获得几乎相同的效果,并且添加方法静态将需要增加复杂性.
其次,方法级别静态有些臭名昭着,在重复调用代码或从多个线程调用代码时会出现问题,并且由于定义在方法中,因此很难找到定义.
[作者:Eric Gunnerson]
我对C语言并不熟悉,因为我是C#,但我相信你可以通过使用仅用于一种方法的类级别静态来完成本地静态的所有操作.显然,这会带来一些语法上的改变,但我相信你可以得到你需要的任何功能.
此外,Eric Lippert在他的博客上回答了很多这样的问题.通常以这种方式回答:"我被问到"为什么C#不能实现功能X?"所有的时间.答案总是一样的:因为没有人设计,指定,实施,测试,记录和发送该功能. " 从本质上讲,他的答案通常归结为,添加任何功能都需要花钱,因此,许多潜在的功能都没有实施,因为它们没有在成本效益分析的积极方面出现.
所以你想在你的方法中使用静态局部变量?恭喜!你朝着成为一名真正的程序员迈出了一步.
不要听所有人告诉你静态本地人不"干净",他们阻碍"可读性",并可能导致微妙和难以发现的"错误".废话!他们只是说,因为他们是崇拜程序员!很多人甚至可能在他们的空闲时间使用深奥的函数式编程语言来玩弄它们.你相信吗?真是一堆赶时髦的人!
真正的程序员拥抱范式我喜欢叫SDD - S ^ IDE效应d里文d ESIGN.以下是一些最重要的法律:
不可预测!永远不要从方法中返回相同的东西两次 - 即使它被使用完全相同的参数调用!
螺杆纯度 - 让我们变脏!国家本质上渴望改变,因为它是多角形内聚合物类别中永不满足的幺半群,即它喜欢被尽可能多的合作者接触.千万不要错过这个有利于它的机会!
用于以副作用驱动方式编码的工具当然是静态局部变量.但是,正如您所注意到的,C#不支持它们.为什么?因为在过去的二十年里,微软已被所谓的清洁编码器渗透,这种编码器有利于可维护性而不是灵活性和控制.你能记得你最后一次看到我们心爱的蓝屏吗?现在猜猜是谁的错!
但不要害怕!真正的开发人员不必遭受那些糟糕的设计决策.如前所述,在lambda的帮助下,局部变量可能是静态的.
但是,提供的解决方案并不十分令人满意.使用前面的答案,我们几乎符合SDD的代码看起来像这样:
var inc = Increment(); var zero = inc(); var one = inc();
要么
var zero = Increment()();
但那太傻了.即使是一个崇拜者开发人员可以看到,Increment()
是不正常的方法,将得到可疑.一个真正的程序员,在另一方面,可以使其更加SDD样.他或她知道我们可以通过赋予它类型来使属性或字段看起来像一个方法Func
!我们只需要通过执行一个lambda来初始化它,而lambda又会初始化计数器并返回另一个lambda来递增捕获的计数器!
这是适当的SDD代码:
public FuncIncrement = new Func >(() => { var num = 0; return () => num++; }).Invoke();
(您认为上述类似于IIFE?是的,您是对的,您应该为自己感到羞耻.)
现在每次调用Increment()
它都会返回不同的东西:
var zero = Increment(); var one = Increment();
当然,您也可以使计数器在您的实例的生命周期中存活.
这会让他们想当程序员!