为什么在C#中需要使用"new"关键字

3
假设我有一个函数foo,它以向量类作为输入:
void Foo( Vector3 vector );

如果我想调用这个函数:

Foo( new Vector3(1, 2, 3) );

为什么在C#中需要使用new关键字?在其他语言,比如C++中,在这种情况下不需要使用new关键字,似乎这是多余的。编辑1:@spender以下代码是完全有效的C++代码。
Foo ( Vector3(1, 2, 3) );

将创建一个Vector3对象在堆栈上,不需要使用new/calloc/malloc。


5
因为类不是函数。 - SLaks
18
在C ++中没有必要使用new。抱歉,什么? - Frédéric Hamidi
3
嗯,实际上并没有专门的方式。在C++中,你可以使用T(args)的语法构建一个临时对象。new通常用于堆构造,并且你几乎不会直接使用它。 - user142019
2
C++中的所有类都是值类型。class关键字是struct关键字的同义词。这使得在堆栈上创建C++类的实例变得容易。但是,如果忘记编写复制构造函数和赋值运算符,就很难避免创建意外副本,从而导致性能下降或内存损坏。显然,在SO上比较C++和托管代码仍然是一个禁忌话题 :( - Hans Passant
6
这实际上是个非常好的问题。我不确定它是否适合这里的主题,因为答案几乎肯定是推测性的,但从技术上讲,这是一个有趣的问题,我敢打赌那些给它点踩的人只是不理解。举个例子:@FrédéricHamidi的评论目前已经得到了14个赞。唉。 - Konrad Rudolph
显示剩余17条评论
1个回答

12
关键字是由语言设计者认为合适。在C#中,这是很常见的,语言强制你意识到正在发生的事情,并在许多情况下提供错误或警告,即使它可以为您隐式添加功能或填充数据。
在C#中,始终需要在使用变量之前进行初始化。在这种情况下,强制使用new关键字使开发人员明显知道(如果Vector3是一个类),新实例将被传递给你的方法,而不是方法调用的结果。
请注意,在C++中,在不更改函数定义的情况下,此处不能省略new。使用new将意味着Foo()需要不同的语法。
没有使用new的调用(Foo(Vector3(1,2,3));)表示Foo定义为void Foo(Vector3 vector)。如果您使用了new Vector3,则Foo将被定义为void Foo(Vector3* vector),因为new将返回指向该类型的指针。
这是因为C++允许多种形式的对象分配-您可以堆栈分配(无需new)或在堆上分配(使用new)。C#没有这种区别-所有引用类型都始终在长期存储中分配,而值类型则根据其上下文和用法在位置上分配。开发人员在对象使用和分配方面在C#中没有像在C++中那样的控制。在一天的结束时,每种(具有对象概念的)语言都有自己的语法和对象初始化及使用规则。每种语言都是独特的,这也是为什么会有这么多不同的编程语言的部分原因。一般来说,大多数语言都是围绕一组主导哲学和方法设计的,并且使用 new 必要性与 C# 的做法相符,即在可能存在歧义时非常明确(例如:这是类型构造函数还是方法?)。

2
你提供的Foo签名示例是错误的。T&不会绑定到临时对象,任何人将裸指针传递给“new”的对象都应该被枪毙,除非在某些非常特殊的情况下。其次,你没有解释为什么构造函数应该与方法有所不同。 - Puppy
@Servy:他已经将T&中的一个编辑掉了(new仍然失败)。但我对这个答案的主要抱怨是他说“需要显式使用new”,但没有说明为什么在这种情况下显式性优于统一性。 - Puppy
我正在点赞这个答案,但我唯一的问题是C#并不总是显式的。一个明显的例子是var关键字,以及许多不同的匿名初始化和lambda语法,C#语法经常不太清晰或明确。 - mao47
1
@Reed,新的可能会产生歧义的唯一情况是存在一个与类同名的方法吗?还有其他不使用“new”会产生歧义的情况吗?如果这是唯一的情况,我完全可以理解废除“new”的论点。 - mao47
1
@mao47 是的,编程语言可以有规则来决定如何在它们之间进行选择 - 但这并没有被这样做(无论是出于好的还是坏的原因 - 设计者选择使构造函数调用显式,并且总是从语法上与方法调用不同) 。 - Reed Copsey
显示剩余7条评论

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