当前位置:  开发笔记 > 编程语言 > 正文

为什么C#不支持C这样的本地静态变量呢?

如何解决《为什么C#不支持C这样的本地静态变量呢?》经验,为你挑选了5个好方法。

为什么C#没有像C这样的局部静态变量?我想念!!



1> 小智..:

因为他们搞砸了,并且遗漏了一个适合自己的有用功能.

关于你应该如何编码以及什么是聪明的,你应该重新考虑你的生活方式的所有争论都是浮夸的防御借口.

当然,C#是纯粹的,而且是以人为本的.这就是他们为lambda函数自动生成持久本地的原因.这一切都很复杂.我觉得很蠢.

在许多情况下,循环范围静态是有用且重要的.

简短而真实的答案是,您必须将本地静态移动到类范围内,并在C#中使用类命名空间污染.把你的投诉带到市政厅.


+1同意,这里的大多数答案都以'你可以通过......等等来实现这一点'结束,但这不足.我可以通过多种方式实现理想的行为,但这不是重点.静态局部变量与静态类变量完全相同,但可见性较低,这是所需的行为.
实际上,VB.NET只是在幕后创建静态类级变量.CLR不支持静态方法变量.
任何时候你说"你能做的任何事情......你也可以这样做"必须结束为什么你不编程图灵机?能够将变量的范围与其生命周期区分开来是非常有用的,并且静态实例字段不会阻止其他开发人员在不应该被篡改时 - 否则,为什么要打扰公共/私有/等等.
实际上它可以在.NET中使用,而不是使用C#.例如,VB.NET支持本地静态变量.
我希望我能给这个答案几千张赞成票。对我而言,与其说是为了证明目的,不如说是防篡改。为了未来我。就像明天,或今天晚些时候。命名某事并不总是那么容易(通常是不可能的),以便使它的所有内容立即显而易见。范围限制对此非常有帮助。极大地。没有足够的理由不限制范围的静态变量。是的,有时您可能会意识到需要在功能之外访问它。因此,如果发生这种情况,请重构并给它更大的名称,更多的文档和更大的范围。

2> Jon Skeet..:

状态通常是对象的一部分或类型的一部分,而不是方法的一部分.(当然,例外是捕获变量.)

如果你想要一个本地静态变量的等价物,要么创建一个实例变量,要么创建一个静态变量 - 并考虑该方法本身是否应该实际上是该状态的不同类型的一部分.


这两个选项都是变通方法,因为它们具有比本地函数更多的可见性.创建一个新类是"更清洁"的解决方案,但现在您需要更多代码来解决缺少的功能.
@JimBalter:我仍然不同意.状态本质上与类型相关联(它在AppDomain存在时存在,并且在类型初始化之前不存在),例如.如果没有广告同性恋攻击可以表达不同意见,我会很感激...
请注意,在C++中,您可以使用静态"变量"作为常量值.由于C#在数学意义上只有常量,因此使用本地计算常量非常繁琐(如sqrt of 2,只是一个例子).
@Ken:但我的观点是,这本身就是一种设计气味.如果编译器支持这一点,则必须将变量提升为实例或静态变量 - 因此它**将成为类或实例状态的一部分.如果这不适合您的课程,那么它是不合适的,但它在源代码中表示.如果它*是*合适的,你为什么要隐瞒那个州?
只是说,我的情况是我需要一个只在一个方法中使用的静态变量,并且在类定义中创建该变量会导致(不需要的)spaghetti代码.

3> Nick Alexeev..:

MSDN博客文章为什么C#不支持静态方法变量?处理原帖中提出的确切问题:

C#没有此功能有两个原因.

首先,通过使用类级静态可以获得几乎相同的效果,并且添加方法静态将需要增加复杂性.

其次,方法级别静态有些臭名昭着,在重复调用代码或从多个线程调用代码时会出现问题,并且由于定义在方法中,因此很难找到定义.

[作者:Eric Gunnerson]


我理解这不一定是你的意见,但是可以为类级静态提供完全相同的论据."多线程很难和bugprone"和"多个用户在内存中修改相同的静态值是更多的bugprone和难以跟踪"是没有借口不包括功能.这些是现有功能集的问题,这些功能并未特别加剧.为了上帝的缘故,他们有静态类和静态构造函数,它们甚至因为难以跟踪甚至更难以进行单元测试而闻名!

4> Timothy Cart..:

我对C语言并不熟悉,因为我是C#,但我相信你可以通过使用仅用于一种方法的类级别静态来完成本地静态的所有操作.显然,这会带来一些语法上的改变,但我相信你可以得到你需要的任何功能.

此外,Eric Lippert在他的博客上回答了很多这样的问题.通常以这种方式回答:"我被问到"为什么C#不能实现功能X?"所有的时间.答案总是一样的:因为没有人设计,指定,实施,测试,记录和发送该功能. " 从本质上讲,他的答案通常归结为,添加任何功能都需要花钱,因此,许多潜在的功能都没有实施,因为它们没有在成本效益分析的积极方面出现.


我自己也不能说得更好.
使用类static实现本地静态的问题是类名空间被不必要地污染.向C#添加功能所需的资源问题是微软(以及其他人,咳嗽,Sun/Oracle)的大多数语言都不是很棒的原因.他们毫无歉意地做了"足够好"而不是好事.
我可以尊重这个答案的第二部分.第一部分是解决方案,但不是借口.在这里,这是重要的一部分.正如其他人所说,"你可以通过做Y来完成X"与"你可以用图灵机模拟任何编程语言的所有功能"没什么不同.然而,我们不这样做是因为尽管它是一个"足够强大的工具",但只有与图灵机具有相同功能的语言(当然除了无限的记忆)之外,它的效率还不够高.

5> Good Night N..:

所以你想在你的方法中使用静态局部变量?恭喜!你朝着成为一名真正的程序员迈出了一步.

不要听所有人告诉你静态本地人不"干净",他们阻碍"可读性",并可能导致微妙和难以发现的"错误".废话!他们只是说,因为他们是崇拜程序员!很多人甚至可能在他们的空闲时间使用深奥的函数式编程语言来玩弄它们.你相信吗?真是一堆赶时髦的人!

真正的程序员拥抱范式我喜欢叫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 Func Increment = new Func>(() =>
{
    var num = 0;
    return () => num++;
}).Invoke();

(您认为上述类似于IIFE?是的,您是对的,您应该为自己感到羞耻.)

现在每次调用Increment() 它都会返回不同的东西:

var zero = Increment();
var one = Increment();

当然,您也可以使计数器在您的实例的生命周期中存活.

这会让他们想当程序员!


这应该是这个问题的严肃答案吗?这感觉更像是一个古老的问题,被用来作为一个平台来咆哮"其他人"糟糕的编程习惯.
推荐阅读
携手相约幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有