我不明白为什么我们需要'新'的关键字 [英] I don't understand why we need the 'new' keyword

查看:101
本文介绍了我不明白为什么我们需要'新'的关键字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



<预类=郎-CPP prettyprint-覆盖> MyClass类{
$ .... b $ b};
INT主要()
{
MyClass的对象; //这会在内存中
MyClass的*对象=新MyClass的创建对象(); //这样做同样的事情
}

然而,在C#中:

 类节目
{
静态无效的主要(字串[] args)
{
车点¯x ;
x.i = 2;
x.j = 3;
Console.WriteLine(x.i);
到Console.ReadLine();

}
}
级轿车
{
公众诠释我;
公众诠释焦耳;


}



你不能做到这一点。我不知道为什么车载X 不会做其工作。


解决方案

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



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

  MyClass的对象; //这会在内存中
MyClass的*对象=新MyClass的创建对象(); //这样做同样的事情



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



首先,这些不这样做在C同样的事情++ ,所以这个问题是基于C ++语言的一个错误的认识。这是,以了解这两种事物之间的区别在C ++ ,所以如果你不明白的很清楚的区别是什么,找一个导师谁可以教你怎么知道有什么区别非常重要,以及何时使用每个



二,问题的先决条件 - 错误 - 这两个语法做同样的事情在C ++中,然后,奇怪的是,问:为什么我们需要在C#中?当然要问这给出正确的问题 - 再次,假的 - 前提是:为什么我们需要在C ++?如果这两种语法做同样的事情 - 他们没有 - 然后点击为什么在第一个地方有两种语法



因此​​,问题是基于一个错误的前提两者,关于C#的问题并没有真正从跟随 - 误解 - 的C ++设计



这是一个烂摊子。让我们把这个问题,并提出一些更好的问题。让我们请教一下C#的 QUA 的C#,而不是C ++的设计决策的背景。




的问题

什么是新X 运算符在C#中,其中X为一类或结构类型呢? (让我们忽略了这个讨论的目的,代表和数组)




new运算符:




  • 导致要分配的给定类型的新实例;新的实例都各自领域的初始化为默认值。

  • 将导致执行给定类型的构造函数。

  • 可生产的参考的所分配的对象,如果该对象是引用类型或值本身,如果对象是一个值类型



好吧,我已经可以听到从C#程序员的反对在那里,让我们把他们辞退



异议:没有新的存储如果分配的类型是值类型,我听你说。那么,C#规范和你意见不同。当你说

 取值S =新S(123); 



对于一些结构类型取值,该规范说的新的临时存储的是在短期内池分配,初始化为它的默认值,构造与运行此设置为参考临时储存,然后将得到的对象的复制取值。然而,编译器的允许的使用,只要它能证明它是不可能在一个安全的程序,成为观察到的优化复制省音优化。 (动作:下不能进行什么情况下复制省略锻炼;给一个程序,将有不同的行为,如果省音是或不使用的一个例子)



异议:可以用默认(S)生产值类型的有效实例;没有构造函数被调用时,我听到你说。这是正确的。我并没有说的方式来创建一个值类型的实例。



在事实上,对于价值型新S()默认(S) 是一样的。



异议:是一个构造真的像形势的新S()执行,如果不存在源代码在C#6,我听你说。这是一个如果树倒在森林中,没有人听到它,它发出声音?题。是否有不执行任何一个构造函数的调用,并在所有没有呼叫之间的区别吗?这不是一个有趣的问题。编译器是免费的Elid到它知道什么都不做的电话。




假设我们有值类型的变量。我们必须初始化变量与制作实例新的




没有。它们的自动初始化的变量,如字段和数组元素,将被初始化为默认值 - 即,在所有的领域本身它们的默认值的结构的价值。



正式参数将与参数进行初始化,效果显着。



所需值类型的局部变量与被明确分配的的读取字段之前,但它不必是的表达。




所以有效,值类型变量自动默认(S)相当于初始化,除非是本地人?







为什么不当地人?




未初始化的本地的使用强烈bug的代码相关联这样做。 C#语言不允许这样,因为这样发现的bug。




假设我们有引用类型的变量。我们必须初始化取值与制作实例




没有。自动初始化变量将用null初始化。当地人可以与任何引用,包括进行初始化,并且必须读取之前被明确赋值。




所以有效,引用类型的变量自动初始化,除非他们是当地居民?







为什么不当地人做?




同样的道理。一个可能的错误。




为什么不自动调用自动默认构造函数初始化引用类型的变量?也就是说,为什么不能让 R R; R R =新R();




嗯,首先,许多类型没有默认构造函数,或者就此而言,是在所有的可访问构造。其次,它似乎不可思议有一个未初始化的本地或外地的数组元素一个规则,一个正式的其他规则,还有一个规则。第三,现有的规则很简单:一个变量必须初始化到一个值;该值可以是任何你喜欢的; 这是为什么一个新的实例所需的必要前提?这将是奇怪的,如果这



  R R; 
如果(X)R = M();否则R = N();



引起的构造函数运行初始化研究




撇开的中的语义的运营商,为什么是必要的语法的能有这样的运营商?




这不是。有任意数量的替代语法可能是语法。最明显的是简单地消除完全。如果我们有一个类 C 使用构造 C(INT)那么我们可以简单地说 C(123)而不是新C(123)。或者,我们可以使用像语法C.construct(123)或一些这样的事情。有任何数量的方式做到这一点,而不运营商。




所以,为什么有吗?




首先,C#的目的是要马上熟悉C ++,Java和JavaScript的用户,以及使用其他语言来表示新的存储一个对象被初始化。



二,句法冗余的适当水平是高度合意。创建对象是特殊的;我们希望调出时,它有自己的运营情况。


I am new to C#, from a C++ background. In C++ you can do this:

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

Whereas, in 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;


}

you can't do this. I wonder why Car x won't do its work.

解决方案

There are a lot of misconceptions here, both in the question itself and in the several answers.

Let me begin by examining the premise of the question. The question is "why do we need the new keyword in C#?" The motivation for the question is this fragment of C++:

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

I criticize this question on two grounds.

First, these do not do the same thing in C++, so the question is based on a faulty understanding of the C++ language. It is very important to understand the difference between these two things in C++, so if you do not understand very clearly what the difference is, find a mentor who can teach you how to know what the difference is, and when to use each.

Second, the question presupposes -- incorrectly -- that those two syntaxes do the same thing in C++, and then, oddly, asks "why do we need new in C#?" Surely the right question to ask given this -- again, false -- presupposition is "why do we need new in C++?" If those two syntaxes do the same thing -- which they do not -- then why have two syntaxes in the first place?

So the question is both based on a false premise, and the question about C# does not actually follow from the -- misunderstood -- design of C++.

This is a mess. Let's throw out this question and ask some better questions. And let's ask the question about C# qua C#, and not in the context of the design decisions of 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.)

The new operator:

  • Causes a new instance of the given type to be allocated; new instances have all their fields initialized to default values.
  • Causes a constructor of the given type to be executed.
  • Produces a reference to the allocated object, if the object is a reference type, or the value itself if the object is a value type.

All right, I can already hear the objections from C# programmers out there, so let's dismiss them.

Objection: no new storage is allocated if the type is a value type, I hear you say. Well, the C# specification disagrees with you. When you say

S s = new S(123);

for some struct type S, the spec says that new temporary storage is allocated on the short-term pool, initialized to its default values, the constructor runs with this set to refer to the temp storage, and then the resulting object is copied to s. However, the compiler is permitted to use a copy-elision optimization provided that it can prove that it is impossible for the optimization to become observed in a safe program. (Exercise: work out under what circumstances a copy elision cannot be performed; give an example of a program that would have different behaviours if elision was or was not used.)

Objection: a valid instance of a value type can be produced using default(S); no constructor is called, I hear you say. That's correct. I didn't say that new is the only way to create an instance of a value type.

In fact, for a value type new S() and default(S) are the same thing.

Objection: Is a constructor really executed for situations like new S(), if not present in the source code in C# 6, I hear you say. This is an "if a tree falls in the forest and no one hears it, does it make a sound?" question. Is there a difference between a call to a constructor that does nothing, and no call at all? This is not an interesting question. The compiler is free to elide calls that it knows do nothing.

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

No. Variables which are automatically initialized, such as fields and array elements, will be initialized to the default value -- that is, the value of the struct where all the fields are themselves their default values.

Formal parameters will be initialized with the argument, obviously.

Local variables of value type are required to be definitely assigned with something before the fields are read, but it need not be a new expression.

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

Yes.

Why not do the same for locals?

Use of an uninitialized local is strongly associated with buggy code. The C# language disallows this because doing so finds bugs.

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

No. Automatic-initialization variables will be initialized with null. Locals can be initialized with any reference, including null, and must be definitely assigned before being read.

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

Yes.

Why not do the same for locals?

Same reason. A likely bug.

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();?

Well, first of all, many types do not have a default constructor, or for that matter, any accessible constructor at all. Second, it seems weird to have one rule for an uninitialized local or field, another rule for a formal, and yet another rule for an array element. Third, the existing rule is very simple: a variable must be initialized to a value; that value can be anything you like; why is the assumption that a new instance is desired warranted? It would be bizarre if this

R r;
if (x) r = M(); else r = N();

caused a constructor to run to initialize r.

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

It's not. There are any number of alternative syntaxes that could be grammatical. The most obvious would be to simply eliminate the new entirely. If we have a class C with a constructor C(int) then we could simply say C(123) instead of new C(123). Or we could use a syntax like C.construct(123) or some such thing. There are any number of ways to do this without the new operator.

So why have it?

First, C# was designed to be immediately familiar to users of C++, Java, JavaScript, and other languages that use new to indicate new storage is being initialized for an object.

Second, the right level of syntactic redundancy is highly desirable. Object creation is special; we wish to call out when it happens with its own operator.

这篇关于我不明白为什么我们需要'新'的关键字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆