开发者

What is causing the "this" pointer to be null within my constructor?

开发者 https://www.devze.com 2023-04-05 01:28 出处:网络
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:

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


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";
  }

}


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.


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消