Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么C#中不允许常量参数? 它看起来很奇怪,尤其是C++开发人员。用C++标记一个参数为“代码> const < /COD>”,以确保该方法中的状态不会改变。也有其他C++特定的原因,例如通过“代码> const REF< /COD>”,以便通过REF并确保状态不会改变。但是为什么我们不能在C#中标记为方法参数const呢_C#_Language Agnostic_Language Design - Fatal编程技术网

为什么C#中不允许常量参数? 它看起来很奇怪,尤其是C++开发人员。用C++标记一个参数为“代码> const < /COD>”,以确保该方法中的状态不会改变。也有其他C++特定的原因,例如通过“代码> const REF< /COD>”,以便通过REF并确保状态不会改变。但是为什么我们不能在C#中标记为方法参数const呢

为什么C#中不允许常量参数? 它看起来很奇怪,尤其是C++开发人员。用C++标记一个参数为“代码> const < /COD>”,以确保该方法中的状态不会改变。也有其他C++特定的原因,例如通过“代码> const REF< /COD>”,以便通过REF并确保状态不会改变。但是为什么我们不能在C#中标记为方法参数const呢,c#,language-agnostic,language-design,C#,Language Agnostic,Language Design,为什么我不能像下面那样声明我的方法 .... static void TestMethod1(const MyClass val) {} .... static void TestMethod2(const int val) {} .... const 在C语言中是“编译时常数”,而不是C++中的“只读,但可能是其他代码可改变的”。C++中的C++模拟>代码> const 是代码> >只读< /代码>,但仅适用于字段。除此之外,在C#中

为什么我不能像下面那样声明我的方法

    ....
    static void TestMethod1(const MyClass val)
    {}
    ....
    static void TestMethod2(const int val)
    {}
    ....
<代码> const 在C语言中是“编译时常数”,而不是C++中的“只读,但可能是其他代码可改变的”。C++中的C++模拟>代码> const <代码>是代码> >只读< /代码>,但仅适用于字段。除此之外,在C#中根本没有类似C++的常量正确性概念


原因很难说清楚,因为有很多潜在的原因,但我的猜测是希望保持语言的简单性,实现第二种方法的不确定优势。

C#中没有常量正确性的原因之一是它在运行时级别不存在。请记住,C#1.0没有任何功能,除非它是运行时的一部分

CLR没有常量正确性概念的几个原因如下:

....
static void TestMethod1(in MyStruct val)
{
    val = new MyStruct;  // Error CS8331 Cannot assign to variable 'in MyStruct' because it is a readonly variable
    val.member = 0;  // Error CS8332 Cannot assign to a member of variable 'MyStruct' because it is a readonly variable
}
....
static void TestMethod2(in int val)
{
    val = 0;  // Error CS8331 Cannot assign to variable 'in int' because it is a readonly variable
}
....
  • 它使运行时复杂化;此外,JVM也没有它,CLR基本上是作为一个项目开始的,创建一个类似JVM的运行时,而不是一个类似C++的运行时
  • 如果在运行时级别上存在const正确性,那么BCL中应该存在const正确性,否则就.NET Framework而言,该功能几乎毫无意义
  • 但是如果BCL需要常量正确性,那么CLR之上的每种语言都应该支持常量正确性(VB、JavaScript、Python、Ruby、F#等),这是不可能实现的
  • 正确性几乎是C++中唯一的语言特征。因此,关于CLR为什么不需要检查异常(这是一种仅限Java语言的特性),它几乎可以归结为相同的论证


    此外,我认为在托管环境中引入这样一个基本类型系统特性时,不可能不破坏向后兼容性。因此,进入C世界时不要指望常数正确性。

    我认为C不常数正确有两个原因

    首先是可理解性。很少有C++程序员理解常数的正确性。
    const int arg
    的简单示例很可爱,但我也看到了
    char*const*const arg
    ——指向非常量字符的常量指针的常量指针。函数指针上的常量正确性是一个全新的混淆级别

    第二个原因是类参数是通过值传递的引用。这意味着已经有两个级别的常量需要处理,没有明显清晰的语法。一个类似的障碍是集合(以及集合集合等)

    正确性是C++系统的重要组成部分。理论上,它可以作为只在编译时检查的东西添加到C#(它不需要添加到CLR,并且不会影响BCL,除非包含const成员方法的概念)


    然而,我认为这是不可能的:第二个原因(语法)将很难解决,这将使第一个原因(可理解性)成为一个更大的问题。

    除了其他好的答案之外,我还将添加另一个为什么不将C风格常量放入C#的原因。你说:

    我们将参数标记为常量,以确保其状态在方法中不会改变

    如果康斯特真的这么做了,那就太好了。康斯特不会那么做。康斯特是个谎言

    Const并不能保证我能真正使用它。假设您有一个接受常量的方法。有两个代码作者:编写调用方的人和编写被调用方的人。被调用方的作者已使该方法采用常量。这两位作者可以假设什么是关于对象的不变量

    没什么。被调用者可以随意丢弃常量并改变对象,因此调用者不能保证调用接受常量的方法实际上不会改变它。类似地,被调用方不能假设对象的内容在被调用方的整个操作过程中不会改变;被调用者可以在const对象的非const别名上调用一些变异方法,现在所谓的const对象已经改变了

    C样式常量不能保证对象不会更改,因此会被破坏。现在,C已经有了一个弱类型系统,在这个系统中,如果你真的想,你可以将double重新解释为int,所以它也有一个关于const的弱类型系统也就不足为奇了。但是C#被设计成一个好的类型系统,一个类型系统,当你说“这个变量包含一个字符串”时,这个变量实际上包含一个对字符串(或null)的引用。我们绝对不想在类型系统中加入C风格的“const”修饰符,因为我们不希望类型系统是一个谎言。我们希望类型系统是强大的,这样您就可以正确地推理您的代码

    C中的Const是一个指南;它的基本意思是“你可以相信我不会试图改变这个东西”。这不应该在类型系统中;类型系统中的内容应该是关于可以推理的对象的事实,而不是它的用法指南

    现在,别误会我;C中的const被严重破坏并不意味着整个概念都是无用的。我希望看到的是C#中一些真正正确且有用的“const”注释形式,人类和编译器都可以使用该注释来帮助他们理解代码,运行时可以使用该注释进行自动并行化和其他高级优化