简体   繁体   English

关于 C#,Unity 中的“新”关键字的困惑

[英]Confusion regarding the 'new' keyword in C#, Unity

Maybe a silly question, but having difficulty understanding it.也许是一个愚蠢的问题,但很难理解。

public class A
{
  public void Message()
    {
      Debug.Log("Some Message")
    }
}

public class B: MonoBehaviour
{
  A obj1 = new A(); //instance of object is made and constructor is called
  A obj2;           // object is made
  
  obj1.Message();
  obj2.Message();

 void Start(){}
 void Update(){}
}

What's the purpose of 'new' keyword if in both cases, the object is able to use methods of the class如果在这两种情况下 object 都能够使用 class 的方法,那么“新”关键字的目的是什么

A obj2;           // object is made

The object is not instantiated at this time, you only told here that you have a variable with the name obj2, and it is hold reference to nothing, in case of class it is null . object此时没有实例化,你在这里只告诉你有一个名为obj2的变量,并且它是保持引用的,对于class它是null You have a class named A and in it, you have a method called Message() and compiler in compile-time have a signal you have Message method defined, and that it is.您有一个名为 A 的 class ,在其中,您有一个名为 Message() 的方法,并且编译器在编译时有一个信号,您已经定义了 Message 方法,并且确实如此。 In this case, this code should throw an exception NullReferenceException在这种情况下,此代码应抛出异常 NullReferenceException

There are a few quirks to Unity which may be tripping you up here. Unity 有一些怪癖,可能会让你在这里绊倒。 Actually, obj2 is not null, because it is of type "A" (not a Monobehavior).实际上,obj2 不是 null,因为它属于“A”类型(不是 Monobehavior)。 Since Class B is derived from Monobehavior, all of its "class variables" (the ones defined in immediate scope) will be instanced by the Inspector automatically.由于 Class B 是从 Monobehavior 派生的,它的所有“类变量”(在直接作用域中定义的变量)都将由 Inspector 自动实例化。 You can read about that here .你可以在这里阅读。

In other words, obj2 will still be usable.换句话说,obj2 仍然可以使用。 This is a property of custom classes in regards to how they are loaded from MonoBehaviors.这是关于如何从 MonoBehavior 加载自定义类的属性。 If class A was also a MonoBehavior, then it would be nullable here, and you would see it as an empty variable in your inspector when Class B is put onto a GameObject.如果 class A 也是 MonoBehavior,那么它在这里可以为空,并且当 Class B 放在 GameObject 上时,您会在检查器中将其视为空变量。 This is the case where Message() would not work, since obj2 would actually be null.这是 Message() 不起作用的情况,因为 obj2 实际上是 null。 Note there are other complications though--if Class A is a MonoBehavior, then you shouldn't be using Constructors on it, you should be using AddComponent().请注意,还有其他复杂情况——如果 Class A 是 MonoBehavior,那么您不应该在其上使用构造函数,而应该使用 AddComponent()。 Also, you can't define two MonoBehaviors in the same script file.此外,您不能在同一个脚本文件中定义两个 MonoBehavior。

Finally, I'm not sure of the specifics here since I haven't tested it, but obj1.Message() may not be able to be called from where you're currently doing it.最后,我不确定这里的细节,因为我还没有测试过,但是 obj1.Message() 可能无法从您当前正在执行的位置调用。 Typically code is run using the Callback functions provided by the MonoBehavior inheritance, ie Start(), Update(), etc. In order to call obj1.Message() at the start of the game, you need to run it from the Start() method.通常代码使用 MonoBehavior inheritance 提供的回调函数运行,即 Start()、Update() 等。为了在游戏开始时调用 obj1.Message(),您需要从 Start( ) 方法。 Let me know if you have any questions and I can clear up anything you find confusing!如果您有任何问题,请告诉我,我可以解决您感到困惑的任何问题!

EDIT: This is only true if obj2 appears in the inspector--if it is public and the class A is tagged as Serializable.编辑:只有当 obj2 出现在检查器中时,这才是正确的——如果它是公共的并且 class A 被标记为可序列化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM