有几件事要记住。 Message 在您的示例中是 type,message 是实际字段或变量的名称。
变量声明
Message message;
您基本上是在声明变量的类型和名称(也可以是 Message foo)。
实例化
new Message();
SomeMethod(new Message());
我们正在创建Message 的新实例。然后,我们使用赋值来存储新实例以保持它。
在第二个示例中,我们将 Message 的新实例传递给期望它的类,即使我们没有将它保存到变量中。
作业
message1 = message2;
非常不言自明。
一次性
Message message = new Message();
我们正在执行上述所有操作。我们正在创建变量,说明什么类型,然后创建一个新实例。这是很常见的。太常见了,以至于人们厌倦了将Message 写三遍,因此 C# 添加了一种新语法,它的作用实际上是相同的,没有区别:
var message = new Message();C# 可以分辨出message is supposed to be and will make message` 那个类型是什么类型,所以我们不必多余。
关于需要在方法中的实例化,您的预感实际上是正确的。
在做
public class Foo
{
public Message message = new Message();
}
是完全有效的 C# 语法,可以正常工作并且可以编译。然而,它在幕后所做的实际上是这样的:
public class Foo
{
public Message message;
public Foo()
{
message = new Message();
}
}
这实际上给我在 Unity 中工作时带来了问题。在 Unity 中,如果创建的对象继承自 MonoBehavior,则不再允许使用构造函数创建它,并且它会以某种方式完全绕过对构造函数的调用。这真的很烦人,而且让事情变得更加复杂。
其中一个复杂因素是这些字段初始值设定项从未被调用,所以我得到空引用异常而没有意识到如何。我花了一段时间才弄清楚。
现在我必须手动将其放入 Unity 在创建对象时调用的 Awake() 方法中,基本上是编译器会做的。
编辑:正如 Thomas Schremser 指出的,var 仅在方法内部有效。
为了更清楚起见,Message message; 是字段减速(如果在函数内部,则为变量减速),其中 Message 是类型,message 是字段/变量。语法为Type memberName = new Type()
字段是属于类的变量,要么属于类实例,要么属于类本身。例如:
public class Foo
{
public class int InstanceField; // This belongs to individual instances
public static int StaticField; // This belongs to the class itself
// (accessed via Foo.StaticField)
public var ImplicitlyType = 3; // ERROR: Fields can't be implicitly typed
public void Bar()
{
int notAField; // This is only accessible in this function,
// Making it a local variable, not a field
var implicitlyType = 4; // This works because implicitlyTyped is a local variable
// It's type is also of int, not var
}
public void Baz(int alsoNotAField)
{
// alsoNotAField is a parameter. It's value will be given from other methods
// alsoNotAField is also only usable in the scope of this method
notAField++; // ERROR: notAField can't be used here, because it's limited to Bar()
}
}
字段是属于类的一类变量,方法是属于类的一类函数。
函数之外的变量称为字段,在 C# 中无法在类之外拥有函数。所以,从某种意义上说,C#只有方法。