在哪些情况下以及为什么要使用“int a = new int”?

40

只是好奇,以下两者有何不同:

int A = 100;
并且
int A = new int();  

我知道new被用于在堆上分配内存..但是我真的不理解这里的上下文。


要简单明了一些,int A=100; 只是声明一个 int 类型的变量 A 并将其初始化为 100。而 int A= new int(); 则是错误的。虽然它也可以写成 int *A = new int();,这意味着在堆栈上为一个 int 类型的变量分配空间,并将其初始化为 0,然后返回该 int 变量的地址给整型指针 A。 - eRaisedToX
2
@eRaisedToX 在值类型上使用 new 运算符并不是错误。https://dev59.com/W2035IYBdhLWcg3wMNGW 它基本上没有任何可观察到的作用。而该标签适用于 C# 而非 C++。 - Tanveer Badar
10个回答

36
static void Main()
{
    int A = new int();
    int B = default(int);
    int C = 100;
    Console.Read();
}

编译成

.method private hidebysig static void  Main() cil managed
{
  .entrypoint
  // Code size       15 (0xf)
  .maxstack  1
  .locals init ([0] int32 A,
           [1] int32 B,
           [2] int32 C)
  IL_0000:  nop
  IL_0001:  ldc.i4.0
  IL_0002:  stloc.0
  IL_0003:  ldc.i4.0
  IL_0004:  stloc.1
  IL_0005:  ldc.i4.s   100
  IL_0007:  stloc.2
  IL_0008:  call       int32 [mscorlib]System.Console::Read()
  IL_000d:  pop
  IL_000e:  ret
} // end of method Program::Main

你可以看到第一个仅仅是初始化,第二个完全相同,第三个是初始化并设置为100。至于生成的IL代码,它们都在一行中进行了初始化。

所以

int A = new int();

与相同

int A = default(int);

它是否与“int a;”相同? - b.holz

22

区别?

后者以A为0结尾,而不是100。

何时使用?

几乎从来没有。或许在一些生成的代码中使用new TypeName()语法更加简单,但即使在这种情况下,default(TypeName)也是首选。

new不会"在堆上分配内存"。它只是初始化一个实例而已。


那么在新关键字中没有任何意义? - Miriah
除非你想要该对象 / 结构的实例,而不仅仅是默认 / null 值。 - Matthew Whited
1
@Miriah - 这里有一个含义:它意味着我们想要初始化一个新的对象或值;它并不严格意味着与堆栈有关。请注意,new在方法隐藏中有另一种用法(作为关键字)。完全无关,但它确实存在。 - Marc Gravell

10

我强烈推荐你阅读dotnet mob的这篇文章:http://codaffection.blogspot.in/2015/02/difference-between-declarations-int-i.html

int A = 100; //Initialises A to 100 manually

假设你声明一个整数为

int A;

要在A上执行进一步的操作,您需要使用整数值初始化A,否则编译器会显示未分配的本地变量使用错误。请按以下方式声明A

int A = new int(); //A initialised to 0 (default value of int)

允许在不手动初始化的情况下对A进行进一步操作 - 我想你现在明白我的意思了。


现在让我们讨论使用 new ()

使用new并不意味着内存将被分配到堆上;如果A是一个局部变量(例如在一个方法中),它将被分配在栈上的内存空间。然而,如果A是类的成员,那么在创建类的实例时会在堆上分配内存。

需要记住的一点是:如果A是静态的,它将始终位于栈内存上!


我喜欢这个解释,但是使用“int x = 0”和“int x = new()”初始化变量之间有什么区别呢? - Stokely
@Stokely int x= 0 和 int x = new int(); 两种情况没有区别,x 都将被初始化为零。 - Shamseer K

9
int A=100;

在堆栈上分配一个int,并将其值设置为100。

int A=new int();

在堆栈上分配一个 int(是的,值类型即使使用 new 关键字也总是在堆栈上分配),并将其值设置为默认值,即 0。


2
“值类型在堆栈上”的说法是误导性的。例如,在结构体数组中,或作为类的字段。这也取决于如何计算“在堆栈上的一个单元,然后复制”。 - Marc Gravell
5
你说了“总是”(always)……而“总是”并不是指“这个具体情况”。 - Marc Gravell
2
永远都是不正确的说法,如果int是一个局部变量,那么它将在栈上,但如果它是一个实例字段,则会在堆上。 - David Klempfner

6
我从另一个链接中看到了这个:
MSDN说:“new运算符也用于调用值类型的默认构造函数。”
在方法内部:
- int x;:在堆栈上分配一个int并不初始化它。 - int x=5;:在堆栈上分配一个int并将其设置为5; - int x=new int();:在堆栈上分配一个int并将其设置为0; - int x=new int(5);:无法编译。 http://msdn.microsoft.com/en-us/library/fa0ab757.aspx

2
myInt = new int();  // Invoke default constructor for int type.

这个语句等同于以下语句:

myInt = 0;         // Assign an initial value, 0 in this example.

使用new操作符会调用特定类型的默认构造函数,并将默认值分配给变量。顺便提一下,整数的默认值是0。
区别在于,使用new操作符无法初始化和设置除默认值以外的任何内容。

它们不一样。请看我的评论。 - Aliostad
初始化值类型: http://msdn.microsoft.com/zh-cn/library/s1ax56ch.aspx 在我的阅读中,由于0是int的默认值,所以myInt = default(int)和myInt = 0将是相同的。 - rucsi
感谢确认我对使用“new”和“default”的怀疑。它们的使用是毫无意义的。似乎最好总是将值类型实例化为您选择的默认值,即使它是0,这样它就始终可用。您还可以避免混淆其自定义默认值应该是什么。 - Stokely

1
我认为在int上添加new是不必要的(因为int具有默认的内存大小)...当我们有一个用户定义的类,并实例化一个对象时,才使用new。
public static Main()
{
  Cat cat1=new Cat();
}

Public class Cat
{
  public bool Sex
  public string Name
}

现在编译器将分配那么多内存给cat1(这个内存大小在Cat类中定义)。

0

我最终发现了我的问题

我修改的是值,而不是对象

这是正确的做法:

 public ActionResult ChangeDefaultUserLockingSetting(int PasswordAttempts, int DefaultLockingTime)
        {
            var defaultAccountSettings = new DefaultAccountSettingsDataContext();

            var accountSettings = defaultAccountSettings.DefaultAccountSettings.First(u => u.id == 1);


            accountSettings.DefaultAccountLockoutTimeSpan = DefaultLockingTime;
            accountSettings.MaxFailedAccessAttemptsBeforeLockout = PasswordAttempts;

            defaultAccountSettings.SubmitChanges();
            return View("Index", loadAdministrationViewModel());
        }

0
"

"int"是一个值类型,因此两个表达式都不会在托管堆上分配内存。第一条语句将把A初始化为您指定的文字。第二条语句将使A保持默认值。

"

0
如果您在类中使用int作为字段,甚至可以简单地说int x; - 因为int是值类型,它不能为null,因此会获得其默认值 - 即0。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接