gpt4 book ai didi

c# - 我不明白为什么我们需要 'new' 关键字

转载 作者:行者123 更新时间:2023-12-02 08:35:57 26 4
gpt4 key购买 nike

我是 C# 新手,有 C++ 背景。在 C++ 中,你可以这样做:

class MyClass{
....
};
int main()
{
MyClass object; // this will create object in memory
MyClass* object = new MyClass(); // this does same thing
}

而在 C# 中:
class Program
{
static void Main(string[] args)
{
Car x;
x.i = 2;
x.j = 3;
Console.WriteLine(x.i);
Console.ReadLine();

}
}
class Car
{
public int i;
public int j;


}

你不能这样做。我想知道为什么 Car x不会做它的工作。

最佳答案

这里有很多误解,无论是在问题本身还是在几个答案中。

让我首先检查这个问题的前提。问题是“为什么我们需要 C# 中的 new 关键字?”这个问题的动机是这个 C++ 片段:

 MyClass object; // this will create object in memory
MyClass* object = new MyClass(); // this does same thing

我基于两个理由批评这个问题。

一、 这些在 C++ 中不做同样的事情 ,所以这个问题是基于对 C++ 语言的错误理解。是 理解 C++ 中这两件事之间的区别非常重要 ,所以如果你不是很清楚区别是什么,找一个导师可以教你如何知道区别是什么,以及何时使用。

其次,这个问题的前提是——错误地——这两种语法在 C++ 中做同样的事情,然后奇怪地问“为什么我们在 C# 中需要 new?”考虑到这一点,肯定要问的正确问题——同样是错误的——预设是“为什么我们需要在 C++ 中 new?”如果这两种语法做同样的事情——他们没有——那么 为什么首先有两种语法?

所以这个问题都是基于一个错误的前提,关于 C# 的问题实际上并不是从 - 被误解的 - C++ 设计中得出的。

这是一团糟。让我们抛开这个问题并提出一些更好的问题。让我们问关于 C# qua C# 的问题,而不是在 C++ 的设计决策的上下文中。

What does the new X operator do in C#, where X is a class or struct type? (Let's ignore delegates and arrays for the purposes of this discussion.)



新运营商:
  • 导致分配给定类型的新实例;新实例的所有字段都初始化为默认值。
  • 导致执行给定类型的构造函数。
  • 如果对象是引用类型,则生成对分配对象的引用,如果对象是值类型,则生成值本身。

  • 好吧,我已经听到 C# 程序员的反对意见,所以让我们驳回他们。

    反对意见:如果类型是值类型,则不会分配新的存储空间,我听到你说。好吧,C# 规范不同意你的看法。当你说
    S s = new S(123);

    对于某些结构类型 S ,规范说在短期池上分配了新的临时存储,初始化为其默认值,构造函数以 this 运行。设置为引用临时存储,然后将生成的对象复制到 s .但是,编译器可以使用复制省略优化,前提是它可以证明优化不可能在安全程序中被观察到。 (练习:找出在什么情况下不能执行复制省略;给出一个如果使用或不使用省略会有不同行为的程序示例。)

    反对意见:可以使用 default(S) 生成值类型的有效实例。 ;没有调用构造函数,我听到你说。没错。我没说 new是创建值类型实例的唯一方法。

    实际上,对于值类型 new S()default(S)是一样的。

    反对意见:构造函数是否真的在 new S() 之类的情况下执行? ,如果没有出现在 C# 6 的源代码中,我听到你说。这是一个“如果一棵树倒在森林里而没有人听到它,它会发出声音吗?”题。调用什么都不做的构造函数和根本不调用之间有区别吗?这不是一个有趣的问题。编译器可以自由地忽略它知道什么都不做的调用。

    Suppose we have a variable of value type. Must we initialize the variable with an instance produced by new?



    不会。自动初始化的变量,例如字段和数组元素,将被初始化为默认值——即结构的值,其中所有字段本身都是它们的默认值。

    显然,形式参数将用参数初始化。

    值类型的局部变量需要在读取字段之前明确赋值,但不必是 new表达。

    So effectively, variables of value type are automatically initialized with the equivalent of default(S), unless they are locals?



    是的。

    Why not do the same for locals?



    使用未初始化的本地与错误代码密切相关。 C# 语言不允许这样做,因为这样做会发现错误。

    Suppose we have a variable of reference type. Must we initialize S with an instance produced by new?



    否。自动初始化变量将被初始化为 null。局部变量可以用任何引用初始化,包括 null ,并且必须在被读取之前明确分配。

    So effectively, variables of reference type are automatically initialized with null, unless they are locals?



    是的。

    Why not do the same for locals?



    同样的原因。一个可能的错误。

    Why not automatically initialize variables of reference type by calling the default constructor automatically? That is, why not make R r; the same as R r = new R();?



    嗯,首先,许多类型没有默认构造函数,或者就此而言, 任何可访问的构造函数 .其次,对未初始化的局部或字段有一个规则,对正式的有另一条规则,对数组元素有另一条规则,这似乎很奇怪。第三,现有规则很简单:一个变量必须初始化为一个值;该值可以是您喜欢的任何值; 为什么需要新实例的假设是有保证的 ?如果这会很奇怪
    R r;
    if (x) r = M(); else r = N();

    导致构造函数运行以初始化 r .

    Leaving aside the semantics of the new operator, why is it necessary syntactically to have such an operator?



    它不是。有许多替代语法可能符合语法。最明显的是简单地消除 new完全。如果我们有一个类 C带有构造函数 C(int)那么我们可以简单地说 C(123)而不是 new C(123) .或者我们可以使用类似 C.construct(123) 的语法或者一些这样的事情。在没有 new 的情况下,有多种方法可以做到这一点。运算符(operator)。

    So why have it?



    首先,C# 旨在让 C++、Java、JavaScript 和其他使用 new 的语言的用户立即熟悉。指示正在为对象初始化新存储。

    其次,非常需要正确级别的句法冗余。对象创建是特殊的;当它发生在它自己的运营商身上时,我们希望大声疾呼。

    关于c# - 我不明白为什么我们需要 'new' 关键字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38099520/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com