为什么C#不支持C这样的本地静态variables呢?
为什么C#没有像C这样的本地静态variables? 我想念那!
你可以使用委托模拟它…这里是我的示例代码:
public Func<int> Increment() { int num = 0; return new Func<int>(() => { return num++; }); }
你可以这样调用它:
Func<int> inc = Increment(); inc();
因为他们搞砸了,而忽略了一个有用的function,以适应自己。
所有关于你应该如何编码,什么是聪明的论点,你应该重新考虑你的生活方式,是自负的辩护理由。
当然,C#是纯粹的,面向什么样的应用程序。 这就是为什么他们自动生成lambda函数的持久化局部。 这一切都很复杂 我觉得很愚蠢。
循环范围静态在许多情况下是有用的和重要的。
简短而真实的答案是,您必须将本地静态数据移动到类范围中,并使用C#中的类名称空间污染。 把你的投诉带到市政厅。
状态通常是对象的一部分或types的一部分,而不是方法的一部分。 (当然是捕获variables的例外。)
如果你想要一个局部静态variables的等价物,可以创build一个实例variables或一个静态variables – 并考虑该方法本身是否应该实际上是与该状态不同types的一部分。
MSDN博客条目为什么C#不支持静态方法variables? 处理原始post中提出的确切问题:
有两个原因C#没有这个function。
首先,通过具有类级静态可以获得几乎相同的效果,并且添加方法静态会需要增加复杂性。
其次,方法级别的静态方法在重复调用代码或从多个线程中调用时会引起问题,而且由于定义在方法中,因此很难find定义。
[作者: Eric Gunnerson]
我并不像C#那样熟悉C,但是我相信你可以通过使用仅用于一种方法的类级别的静态来完成所有你可以使用本地静态的方法。 显然,这带有一些语法变化,但我相信你可以得到你需要的任何function。
另外,Eric Lippert在他的博客上也回答了这样的问题。 一般这样回答:“我总是被问到”为什么C#没有实现特性X?“答案总是一样的,因为从来没有人devise,指定,实现,testing,logging和发布该特性。 “ 从本质上讲,他的答案通常归结为:添加任何特征都需要花钱,因此许多潜在特征没有实现,因为它们没有在成本效益分析的积极方面出现。
所以你想在你的方法中使用静态局部variables? 恭喜! 你迈出了成为真正的程序员的又一步。
不要听所有的人告诉你,静态的本地人不是“干净的”,他们妨碍“可读性”,并可能导致微妙和难以发现的“错误”。 废话! 他们只是说,因为他们是想要程序员! 他们中的很多人可能在闲暇时间用一种深奥的函数式编程语言来玩耍。 你相信吗? 什么一堆赶时髦的人!
真正的程序员拥抱一个我喜欢称之为SDD – S效果的devise模式 。 这是一些最重要的法律:
不要预测! 从来没有两次从一个方法返回相同的东西 – 即使它被调用的确实相同的参数!
螺丝纯度 – 让我们变脏! 国家本质上是渴望改变的,因为它是一个多元内部pipe理者类别中无法无天的幺半群 ,即它喜欢被尽可能多的合作者所触及。 千万不要错过这个机会去做它的青睐!
用于以副作用驱动方式编码的工具当然是静态局部variables。 但是,正如您注意到的那样,C#不支持它们。 为什么? 因为在过去的二十年中, 微软已经被所谓的“ 清洁编码器”所渗透,这种清理编码器的可维护性优于灵活性和可控性。 你还记得上一次你看到我们心爱的蓝屏吗? 现在猜猜是谁的错!
但是不要害怕! 真正的开发人员不必从这些糟糕的devise决策中受益。 正如前面提到的,在lambdas的帮助下,可能有局部variables是静态的。
但是,提供的解决scheme并不令人满意。 使用以前的答案,我们几乎与SDD兼容的代码看起来像这样:
var inc = Increment(); var zero = inc(); var one = inc();
要么
var zero = Increment()();
但是,这只是愚蠢的。 即使是一个渴望的开发者也可以看到Increment()
不是一个正常的方法,并且会产生怀疑。 一个真正的程序员,另一方面,可以使它更像SDD。 他或她知道我们可以通过赋予typesFunc<T>
来使属性或字段看起来像一个方法! 我们只需要通过执行一个lambda来初始化它,然后初始化计数器并返回另一个lambda递增捕获的计数器!
这是在适当的SDD代码:
public Func<int> Increment = new Func<Func<int>>(() => { var num = 0; return () => num++; }).Invoke();
(你认为上面的那个看起来像一个IIFE ?是的,你是对的,你应该为自己感到羞愧。)
现在每次调用Increment()
,都会返回一些不同的东西 :
var zero = Increment(); var one = Increment();
当然你也可以做到这一点,以便柜台在你的实例的一生中幸存下来 。
这将显示他们想要程序员!
C#是一种面向组件的语言,不具有超出类或本地方法范围的variables的概念。 一个方法中的variables也不能被声明为静态的,因为你可能习惯在C中进行操作。不过,你总是可以使用一个类的静态variables作为替代。
作为一般的做法,通常有很多方法可以解决C#中的编程问题,而无需使用方法级别的静态方法。 状态通常是你应该devise成类和types的东西,而不是方法。
从逻辑上说,是的。 它将与仅在该方法中使用的类级静态成员相同。 但是,方法级别的静态成员会被封装得更多。 如果存储在成员中的数据只能用于单个方法,则只能通过该方法访问。
但是,通过创build嵌套类,您可以在C#中获得几乎完全相同的效果。
因为静态局部variables绑定到方法,并且方法在所有实例之间共享。
我不得不纠正自己和其他程序员谁希望它是唯一的每个类实例使用该方法。
但是,如果将其设置为静态类或类的静态实例,则在语法上将清楚每个容器类是否有实例,或者是否有一个实例。
如果不使用这些,那么稍后重构也变得更容易。
我认为,通过为这个类创build公共静态字段,就可以轻松解决本地静态的问题。 很less有逻辑上的变化,你不觉得吗?
如果你认为这将是一个很大的逻辑变化,我会有兴趣听到如何。
class MyClass { public static float MaxDepthInches = 3; private void PickNose() { if (CurrentFingerDepth < MyClass.MaxDepthInches) { CurrentFingerDepth++; } } }
如果你能想象某种Lippert / Farnsworth混合实体宣布好消息大家! ,C#6.0允许using static
语句。 这有效地允许你导入静态类方法(看起来,属性和成员)以及全局范围。
总之,你可以做这样的事情:
using NUnit.Framework; using static Fizz.Buzz; class Program { [Test] public void Main() { Method(); int z = Z; object y = Y; Y = new object(); } } namespace Fizz { class Buzz { public static void Method() { } public static int Z; public static object Y { get; set; } } }
虽然这只在C#6.0中可用,但据我所知,生成的程序集应该与以前的.NET平台兼容(纠正我,如果我错了)。