我是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);
输出结果为:
构造函数执行
空
null
我需要将引用存储在列表中,但现在我不能。我该如何解决这个问题?
好的实际代码是
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");
}
输出:
构造函数执行
OK
它的空
答案 0 :(得分:3)
这是不可能的。
this
关键字永远不能是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";
}
}
答案 1 :(得分:3)
请注意:问题中的代码本身并不是实际代码(如评论中所述)导致人们走错路径(Wire类应该显示为继承自MonoBehavior )。目前接受的答案与本案中发生的事情无关。
真正的问题是,上面的代码继承自MonoBehavior。在这种情况下,如果使用new实例化类,则确实会为true
返回(this == null)
而对(this != null)
返回false。当然,您仍然可以访问此成员,因为该对象实际上不是null
,只是==
和=!
运算符过载。
在Unity中,对于任何继承自UnityEngine.Object
(或任何子类,显然)的类来说,通过new实例化类是未定义的行为。要创建此类对象,您必须使用UnityEngine.Object.CreateInstance
,MonoBehavior.Instantiate
或其他类似对象。重载的==
/ =!
运算符可能会检查由这些自定义实例化方法设置的某些标志。
答案 2 :(得分:2)
问题在于,它是不完整的。
this
关键字永远不会为null,因为它只在类的实例成员中具有范围。如果存在实例,this
不为空,那么根据定义它永远不会为空。
当您将参数传递给WriteLine
时,它只会在参数上调用ToString
。如果传递一个参数(如类引用),它将打印出类型名称(如果未覆盖)。在您的情况下,必须重写它才能返回字符串文字“null”。传递null
参数,例如:
string s = null;
Console.WriteLine(s);
根本不打印任何内容。
如果要将引用存储在列表中,则不存储引用的字符串表示形式,而是存储引用本身:
List<Wire> wires = new List<Wire>();
wires.Add(new Wire());
更新:除非您自己实施,否则C#没有“正常的复制构造函数”。但是,即使您自己实现,也会创建一个不同的对象。
答案 3 :(得分:0)
我不确定为什么会这样,但是当我打电话时: Debug.Log(“LevelColection构造函数”+ this);
我得到了相同的结果: LevelColection构造函数为null UnityEngine.Debug:日志(对象)
编辑: 因此,如果继承MonoBehaviour,则不会创建对象。对我有用的东西就是删除:MonoBehaviour,它就像魅力一样。祝你今天愉快。