首页 > 解决方案 > 我制作的示例代码中的这个“变量”/“实例化”到底是什么?

问题描述

所以我对类及其变量有一些疑问,主要是关于“消息消息”;在我之前写的代码中。

我的主要问题是:为什么我可以Message message;在类范围内声明它而不需要将它放在方法范围内?因为我认为需要将实例化放入方法中,此外,这到底是什么Message message;?它是一个变量吗?是实例化吗?

public class Message
{
    public string MessageValue() => "Hello World";
}
public class Write
{
    Message message;
    private void printMessage() => Console.WriteLine(message.messagevalue());
}

标签: c#classvariablesinstantiation

解决方案


有几件事要记住。Message在您的示例中是类型,并且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,则不再允许使用构造函数创建它,并且它以某种方式完全绕过了对构造函数的调用。它真的很烦人,并使事情变得更加复杂。

复杂性之一是这些字段初始化程序从未被调用,所以我得到空引用异常而没有意识到如何。我花了一段时间才弄清楚。

现在我必须手动将它放在Awake()Unity 在创建对象时调用的方法中,基本上是编译器会做的。

编辑:正如 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#只有方法。


推荐阅读