为什么要在使用之前实例化

本文关键字:实例化 为什么 | 更新日期: 2023-09-27 18:13:47

我不明白为什么或者如何能够在类开始时实例化一个变量并且不给它分配任何值,但是一旦我进入类的编码,我就能够分配它来使用它。例如,在Unity中,我可以:

public class MapGenerator : MonoBehaviour {
// right here I can instantiate the variable...
    public int width;
    public int height;
// and then here I actually use it!!
    void GenerateMap() {
        map = new int[width,height];
        RandomFillMap();
谁能帮我澄清一下吗?

为什么要在使用之前实例化

Value Types (c# Reference)

每个值类型都有一个隐式的默认构造函数来初始化该类型的默认值。

指出:

  • 注意,初始化器只对类成员运行。
  • 局部变量在使用前必须初始化。

类型默认值:

bool: false
byte: 0
char: ''0'
decimal: 0.0M
double: 0.0D
enum: The value produced by the expression (E)0, where E is the enum identifier.
float: 0.0F
int: 0
long: 0L
sbyte: 0
short: 0
struct: The value produced by setting all value-type fields to their default values and all reference-type fields to null.
uint: 0
ulong: 0
ushort: 0

Class Member - OK

public class Sample1
{
    int i;
    public void PrintI()
    {
        //Prints 0
        Console.WriteLine(i.ToString());
    }
}

局部变量- ERROR

public class Sample2
{
    public void PrintI()
    {
        int i;  
        //Compile Error: Use of unassigned local variable 'i'
        Console.WriteLine(i.ToString());
    }
}

JSL§4.12.5规定:

程序中的每个变量在其值之前必须有一个值使用:

每个类变量、实例变量或数组组件都是在创建时使用默认值初始化(§15.9,§15.10):

对于byte类型,默认值为0,即值为(字节)0。

对于short类型,默认值为0,即值为(短)0。

对于int类型,默认值为0,即0。

对于long类型,默认值为0,即0L。

对于float类型,默认值为正零,即0.0f。

对于double类型,默认值为正零,即0.0d。

对于char类型,默认值是空字符,即:"' u0000"。

对于boolean类型,默认值为false。

对于所有引用类型(第4.3节),默认值为null。

你给出的代码在Java中隐式地做到了这一点:

public int width;
public int height;
public MapGenerator() { // Constructor
    width = 0;
    height = 0;
}
void GenerateMap() {
    map = new int[width,height];
}

这是值类型和引用类型的区别。

值类型(通过值传递)就是值。而引用类型是对值所在位置的引用。

所有类型都有一个默认值,对于引用类型,它是null,你可以认为"指向Nothing",对于值类型,它不能是,一个值不能为空,所以有一个默认值。

这里它工作是因为int是一个值类型,这意味着即使初始化它也有一个默认值(对于所有数字类型,值为0),如果它是一个引用类型,当你试图在未初始化的情况下使用它时,你会得到一个NullReferenceException。

例如:

 public class Player
 {
      public string Name;
 }
  int i; // This is the same as int i = 0 as default(int) == 0
  i.ToString(); // does not crash as i has a default value;
  Player p; // This is a reference type, the value fo default(Player) is null
  p.ToString(); // This will crash with a NullReferenceException as p was never initialized and you're effectivelly calling a method on "null".

就像那些家伙说的…每个变量类型都有一个默认值…如果你没有给变量赋任何值,它就会被赋一个默认值…但是如果你想在创建对象或实例化它的时候给变量另一个值你可以使用这样的构造函数

public class MapGenerator
{
    public int width;
    public int height;
    public MapGenerator(int Con_width, int Con_height)
    {
        width = Con_width;
        height = Con_height;
    }
}

现在你创建的类的任何对象都必须有宽度和高度的值

MapGenerator mymap = new MapGenerator(200,200);

现在如果你尝试了常规对象

  MapGenerator mymap = new MapGenerator();

它会给你一个错误,因为你将这个默认构造函数更改为新的自定义构造函数

相关文章: