Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在我制作的示例代码中,这个“变量”/“实例化”到底是什么?_C#_Class_Variables_Instantiation - Fatal编程技术网

C# 在我制作的示例代码中,这个“变量”/“实例化”到底是什么?

C# 在我制作的示例代码中,这个“变量”/“实例化”到底是什么?,c#,class,variables,instantiation,C#,Class,Variables,Instantiation,所以我对类及其变量有一些疑问,主要是关于消息;在我之前写的代码中 我的主要问题是:为什么我可以声明此消息;在类作用域中,我不需要将它放在方法作用域中?因为我认为实例化需要放在一个方法中,而且,这个消息到底是什么;它是一个变量吗?它是一个实例吗 public class Message { public string MessageValue() => "Hello World"; } public class Write { Message message; pri

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

我的主要问题是:为什么我可以声明此消息;在类作用域中,我不需要将它放在方法作用域中?因为我认为实例化需要放在一个方法中,而且,这个消息到底是什么;它是一个变量吗?它是一个实例吗

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

让我们看看write类并深入了解它:

public class Write
{
    Message message;
    private void printMessage() => Console.WriteLine(message.messagevalue());
}
信息;是一个字段,该字段的作用域是一个名为message的类实例

字段的定义来自:

字段是直接在类中声明的任何类型的变量 或结构。字段是其包含类型的成员

这意味着message是message类的字段类型,您可以使用它通过Write类访问message类

例如:

Write write = new Write();
write.message = new Message();
message.messagevalue();
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()
        
    }
}

有几件事要记住。示例中的Message是类型,Message是实际字段或变量的名称

变量声明 您基本上是在声明变量的类型,以及名称,也可以是messagefoo之类的东西

实例化 我们正在创建Message的新实例。然后,我们使用赋值来存储新实例以保持它

在第二个示例中,我们将消息的一个新实例传递给期望它的这个类,即使我们没有将它保存到变量中

分配 非常不言自明

突然 在这里,我们正在做上述所有工作。我们正在创建变量,说出类型,然后创建一个新实例。这是很常见的。如此普遍,以至于人们厌倦了三次写出消息,因此C添加了一种新语法,它可以毫无差别地完成相同的事情:

var消息=新消息;C可以告诉message应该是什么类型,并将message设置为那种类型,所以我们不必是多余的

关于实例化需要在方法中,您的直觉实际上是正确的

是完全有效的C语法,可以很好地工作,并且可以编译。然而,它在引擎盖下所做的实际上是:

public class Foo
{
    public Message message;

    public Foo() 
    {
        message = new Message();
    }
}
这实际上给我在团结中工作带来了一个问题。在Unity中,如果创建的对象继承自MonoBehavior,则不允许再使用构造函数来创建它,并且它会以某种方式完全绕过调用构造函数。这真的很烦人,让事情变得复杂多了

其中一个复杂问题是,这些字段初始值设定项从未被调用,因此我在没有意识到如何调用的情况下得到了空引用异常。我花了一段时间才弄明白

现在我必须手动将其放入Unity在创建对象时调用的Awake方法中,这基本上是编译器应该做的

编辑:正如Thomas Schremser指出的,var只在方法内部起作用

至于更多的澄清,信息;如果在函数内,则为字段减速变量减速,其中消息为类型,消息为字段/变量。语法为Type memberName=new Type

字段是属于类的变量,属于类实例或类本身。例如:

Write write = new Write();
write.message = new Message();
message.messagevalue();
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只有方法。

为什么我可以声明此消息;在类作用域中,我不需要将它放在方法作用域中?C中的术语是字段。它是一个变量,作用域是类的实例,而不是方法。我怀疑你想用Message=新消息;否则,您将得到一个异常,因为消息为null而未实例化。您定义了一个引用类型为message的字段。但您尚未在该字段中创建实例。它的初始值为空。因此,您的WriteLine将抛出NullPointerException。您需要将messagevalue设置为静态方法以像上面那样调用它。您声明了一个null变量并调用了一个非静态方法!回答得好。但是,由于OP讨论了字段,值得一提的是var不适用于这些字段。非常感谢您在这里讲了很多事情,但是我在另一条评论中也看到了一件事,消息;那是一块田吗?您可以通过变量Message访问类消息中的不同属性和值谢谢,我用更多信息更新了我的答案。因此字段和变量之间的主要区别在于,在字段中,您可以操作字段类型中的方法和值?那将是一节课,非常感谢btw@LucasMella不完全是。首先,字段和变量
E不是对立的,正如MS文档所说,字段是一个变量,只是处于不同的位置。变量成为字段的原因是它是否在类的主体中声明。如果它是在函数中声明的,那么它只是一个变量。您不能从函数外部访问该变量,即使在同一个类中也不行,然而,如果它是公共字段,则可以。我不知道你说的在野外是什么意思。所有字段都是内存地址。变量也可以操纵它所属类型的方法和值。它们不必都在一个类中,也可以是一个结构。主要区别在于它们是在哪里写的,在哪里可以访问。
public class Foo
{
    public Message message = new Message();
}
public class Foo
{
    public Message message;

    public Foo() 
    {
        message = new Message();
    }
}
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()
        
    }
}