关键字"new"对C#中的结构有什么作用?

KMC*_*KMC 64 c# struct object

在C#中,结构是根据值进行管理的,对象是引用的.根据我的理解,在创建类的实例时,关键字new会导致C#使用类信息来创建实例,如下所示:

class MyClass
{
    ...
}
MyClass mc = new MyClass();
Run Code Online (Sandbox Code Playgroud)

对于struct,您不是创建对象而只是将变量设置为值:

struct MyStruct
{
    public string name;
}
MyStruct ms;
//MyStruct ms = new MyStruct();     
ms.name = "donkey";
Run Code Online (Sandbox Code Playgroud)

我不明白的是,如果声明变量by MyStruct ms = new MyStruct(),new这里的关键字是什么?.如果struct不能成为对象,那么new这里实例化是什么?

jos*_*ndo 57

来自struct (C# Reference)MSDN:

使用new运算符创建结构对象时,会创建它并调用相应的构造函数.与类不同,可以在不使用new运算符的情况下实例化结构.如果不使用new,则字段将保持未分配状态,并且在初始化所有字段之前无法使用该对象.

根据我的理解,除非确保手动初始化所​​有字段,否则实际上无法在不使用new的情况下正确使用结构.如果使用new运算符,构造函数将为您执行此操作.

希望能搞清楚.如果您需要澄清,请告诉我.


编辑

有一个很长的评论帖子,所以我想我会在这里添加更多.我认为理解它的最好方法就是试一试.在Visual Studio中创建一个名为"StructTest"的控制台项目,并将以下代码复制到其中.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace struct_test
{
    class Program
    {
        public struct Point
        {
            public int x, y;

            public Point(int x)
            {
                this.x = x;
                this.y = 5;
            }

            public Point(int x, int y)
            {
                this.x = x;
                this.y = y;
            }

            // It will break with this constructor. If uncommenting this one
            // comment out the other one with only one integer, otherwise it
            // will fail because you are overloading with duplicate parameter
            // types, rather than what I'm trying to demonstrate.
            /*public Point(int y)
            {
                this.y = y;
            }*/
        }

        static void Main(string[] args)
        {
            // Declare an object:
            Point myPoint;
            //Point myPoint = new Point(10, 20);
            //Point myPoint = new Point(15);
            //Point myPoint = new Point();


            // Initialize:
            // Try not using any constructor but comment out one of these
            // and see what happens. (It should fail when you compile it)
            myPoint.x = 10;
            myPoint.y = 20;

            // Display results:
            Console.WriteLine("My Point:");
            Console.WriteLine("x = {0}, y = {1}", myPoint.x, myPoint.y);

            Console.ReadKey(true);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

玩弄它.删除构造函数,看看会发生什么.尝试使用只初始化一个变量的构造函数(我已经注释了一个......它不会编译).尝试使用和不使用关键字(我已经注释掉了一些示例,取消注释并试一试).

  • @joshhendo:嗯?结构的实例是一个对象,它们当然可以包含方法和私有字段.你在这里混淆了初学者. (6认同)

naw*_*fal 16

从这个帖子中抓住Eric Lippert的优秀答案.引用他:

当你"新"一个值类型时,会发生三件事.首先,内存管理器从短期存储中分配空间.其次,构造函数传递对短期存储位置的引用.构造函数运行后,短期存储位置中的值将被复制到值的存储位置,无论发生在何处.请记住,值类型的变量存储实际值.

(请注意,如果编译器可以确定这样做从未将部分构造的结构体暴露给用户代码,则允许编译器将这三个步骤优化为一步.也就是说,编译器可以生成简单地将引用传递给最终结构的代码存储位置到构造函数,从而节省一个分配和一个副本.)

(做出这个答案,因为它真的是一个)

  • 我认为不同的语言群体可能对.NET应该是什么有自己的看法,并假装它符合他们的愿景.例如,C#组可能认为.NET*应该*具有可强制执行的`out`参数,如果每个人都用C#编程,那么带有`out`参数的虚拟方法将被其他语言视为虚拟方法使用`ref`参数.在某些情况下,语言不仅限于其他语言实现者可能想要实现的最小功能子集,这也很好,但也存在危险. (2认同)

Owe*_*lds 5

在结构体中,new关键字不必要地造成混淆。它没有任何作用。如果您想使用构造函数,则这是必需的。它执行new.

的通常含义new是分配永久存储(在堆上)。像 C++ 这样的语言允许new myObject()或只是myObject()。两者都调用相同的构造函数。但前者创建一个新对象并返回一个指针。后者只是创建一个临时变量。任何结构或类都可以使用其中之一。new是一种选择,它意味着什么。

C# 不给你选择。类始终位于堆中,结构始终位于堆栈中。无法对new结构执行实数运算。经验丰富的 C# 程序员对此已经​​习以为常。当他们看到时ms = new MyStruct();,他们知道忽略newas just 语法。他们知道它的行为就像ms = MyStruct(),它只是分配给一个现有的对象。

奇怪的是(?),类需要new. c=myClass();不允许(使用构造函数设置现有对象的值c。)您必须制作类似的东西c.init();。所以你真的没有选择——构造函数总是为类分配,而不是为结构分配。永远new只是装饰。

我认为在结构中需要 fake 的原因new是这样您可以轻松地将结构更改为类(假设您myStruct=new myStruct();在第一次声明时总是使用,这是推荐的。)

  • 令人困惑的是,人们将这个问题解读为“为什么我应该将 new 与结构一起使用”。但如果你读了它,问题实际上是最后一句话“这里实例化的新内容是什么?” 问题在于他们为什么选择这种有趣的语法。 (2认同)