是什么导致了“这个”?我的构造函数中的指针为空?

发布于 2024-12-04 11:26:42 字数 1260 浏览 2 评论 0原文

我是 c# 新手,将其与 unity3D 一起使用。当我使用 new 关键字初始化一个对象时,即使创建了该对象并且执行了构造函数,它似乎也有 null :

public class Wire
{
  public Wire()
  { 
    System.Console.WriteLine("constructor executed");
    System.Console.WriteLine(this);
  }
}

Wire wire1 =new Wire();
System.Console.WriteLine(wire1);

输出是:

构造函数执行

我需要将引用存储在列表中,但现在不能。我该如何解决这个问题?


好的,实际的代码是

public class SharedResources
{    
    public static Dictionary< GameObject , Wire> dict = 
       new Dictionary<GameObject, Wire>();
    //...
}

public class Wire
{
    public GameObject x = y.y; 
    //y.y is another gameobject so its a normal copy constructer

    public Wire()
    { 
        print("constructor executed"); 
        // print is provided from unity package
        SharedResources.dict.Add( x,this);
    }
}

,主要是我有

Wire wire1 = new Wire();
if ( SharedResources.dict.ContainsKey( wire1.x) )
{
    print("ok"); // it does print that!!
    if ( SharedResources.dict[wire1.x] !=null )
        print("its not null");
    else
        print("its null");
}

输出:

构造函数执行
好的
它为空

I am new to c# and use it with unity3D. When I use the new keyword to initialize an object it seems to have null in it even though the object is created and the constructor executes:

public class Wire
{
  public Wire()
  { 
    System.Console.WriteLine("constructor executed");
    System.Console.WriteLine(this);
  }
}

Wire wire1 =new Wire();
System.Console.WriteLine(wire1);

The output is:

constructor executed
null
null

I need to store the reference in a list but now I can't. How can I solve this problem?


ok the actual code is

public class SharedResources
{    
    public static Dictionary< GameObject , Wire> dict = 
       new Dictionary<GameObject, Wire>();
    //...
}

public class Wire
{
    public GameObject x = y.y; 
    //y.y is another gameobject so its a normal copy constructer

    public Wire()
    { 
        print("constructor executed"); 
        // print is provided from unity package
        SharedResources.dict.Add( x,this);
    }
}

and in the main i have

Wire wire1 = new Wire();
if ( SharedResources.dict.ContainsKey( wire1.x) )
{
    print("ok"); // it does print that!!
    if ( SharedResources.dict[wire1.x] !=null )
        print("its not null");
    else
        print("its null");
}

output:

constructor executed
ok
its null

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

旧人 2024-12-11 11:26:42

那是不可能的。

this 关键字永远不能是 null 引用,构造函数永远不能返回 null 引用,并且使用 null 引用调用 Console.WriteLine 不会不显示“null”,它显示一个空行,即与Console.WriteLine(String.Empty)相同。

如果您重写 ToString 方法以返回字符串 "null",则可以获得该行为:

public class Wire {

  public Wire() {
    System.Console.WriteLine("constructor executed");
    System.Console.WriteLine(this);
  }

  public override string ToString() {
    return "null";
  }

}

That is not possible.

The this keyword can never be a null reference, a constructor can never return a null reference, and calling Console.WriteLine with a null reference doesn't display "null", it displays an empty line, i.e the same as Console.WriteLine(String.Empty).

You can get that behaviour if you override the ToString method to return the string "null":

public class Wire {

  public Wire() {
    System.Console.WriteLine("constructor executed");
    System.Console.WriteLine(this);
  }

  public override string ToString() {
    return "null";
  }

}
羁客 2024-12-11 11:26:42

请注意:问题本身的代码永远不是实际代码(如注释中所述),导致人们走上错误的道路(Wire 类应该显示为继承自 MonoBehavior)。目前接受的答案与本案发生的情况无关。

真正的问题是,上面的代码继承自MonoBehavior。在这种情况下,如果你用 new 实例化该类,它确实会为 (this == null) 返回 true,为 (this != null)<返回 false /代码>。当然,您仍然可以访问此对象的成员,因为该对象实际上并不是 null,它只是 ===! 重载的运算符。

发生的事情是,在 Unity 中,对于任何继承自 UnityEngine.Object(或任何子类,显然)的类,通过 new 实例化该类都是未定义的行为。要创建此类对象,您必须使用 UnityEngine.Object.CreateInstanceMonoBehavior.Instantiate 等。重载的 == / =! 运算符可能会检查这些自定义实例化方法设置的某些标志。

Please Note: The code in the question itself is never what the actual code is (as stated in the comments) leading people down the wrong path (the Wire class should be shown to inherit from MonoBehavior). And the currently accepted answer has nothing to do with what's happening in this case.

The real issue is, the above code inherits from MonoBehavior. In that case, if you instantiate the class with new it will indeed return true for (this == null) and false for (this != null). Of course you will still be able to access members of this because the object isn't actually null, it is just the == and =! operators which are overloaded.

What is going on is that in Unity, for any class that inherits from UnityEngine.Object (or any subclasses, obviously) it is undefined behavior to instantiated the class via new. To create such objects you have to use UnityEngine.Object.CreateInstance, MonoBehavior.Instantiate or some such. The overloaded == / =! operators probably check for some flag that is set by these custom instantiate methods.

单调的奢华 2024-12-11 11:26:42

就问题而言,它是不完整的。

this 关键字永远不会为 null,因为它只在类的实例成员内部有效。如果有一个实例,this 不为 null,因此根据定义它永远不会为 null。

当您将参数传递给 WriteLine 时,它只需对该参数调用 ToString 即可。如果您传递一个参数(例如类引用),如果未覆盖,它将打印出类型名称。在您的情况下,必须重写它才能返回字符串文字“null”。传递 null 参数,例如:

string s = null;
Console.WriteLine(s);

Simply 不打印任何内容。

如果要将引用存储在列表中,则不存储引用的字符串表示形式,而是存储引用本身:

List<Wire> wires = new List<Wire>();
wires.Add(new Wire());

更新: C# 没有“普通复制构造函数”,除非你自己已经实现了一个。然而,即使您自己实现一个对象,它也会创建一个不同的对象。

As the question stands, it is incomplete.

The this keyword will never be null because it only has scope inside instance members of a class. If there is an instance, this is not null, so by definition it can never be null.

When you pass an argument into WriteLine, it simply calls ToString on the argument. If you pass an argument such as a class reference, it will print out the type name if not overridden. In your case, it must be overridden in order to return the string literal "null". Passing a null argument such as:

string s = null;
Console.WriteLine(s);

Simply doesn't print anything.

If you want to store the reference in a list, you don't store a string representation of the reference, you store the reference itself:

List<Wire> wires = new List<Wire>();
wires.Add(new Wire());

Update: C# doesn't have a "normal copy constructor" unless you have implemented one yourself. However, even if you implement one yourself, it creates a different object.

少年亿悲伤 2024-12-11 11:26:42

我不确定为什么会发生这种情况,但是当我打电话时:
Debug.Log("LevelCollection构造函数" + this);

我得到相同的结果:
LevelCollection 构造函数 null
UnityEngine.Debug:日志(对象)

编辑:
因此,如果继承MonoBehaviour,则不会创建该对象。对我有用的就是删除 : MonoBehaviour ,它就像魅力一样。祝你今天过得愉快。

I am not sure why this is happening but when i call :
Debug.Log ("LevelColection constructor " + this);

I get the same result:
LevelColection constructor null
UnityEngine.Debug:Log(Object)

Edit:
So the object is not created if you inherit MonoBehaviour. The thing that worked for me was just remove the : MonoBehaviour and it worked like charm. Have a nice day.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文