C# - 为什么需要实例化每个数组元素?

4
我经常使用这种结构。
response = new LocationResponse ();
response.LocationDetails = new LocationDetail[4];
response.LocationDetails[0] = new LocationDetail();
response.LocationDetails[0].site = "ABCDE";
...

我不完全明白的是这一段:

response.LocationDetails[0] = new LocationDetail();

为什么要实例化数组的每个元素?

如果不实例化,会出现未定义异常。

8个回答

13

如果数组元素被自动实例化,您将被限制于使用定义数组时指定的类。您将无法使用抽象类或接口的数组,或任何没有默认构造函数的对象。这只是自动实例化数组对象时遇到的一些问题。


如果类没有默认构造函数呢? - Samuel
没有办法让对象自动实例化。 - kemiller2002

4

如果LocationDetail是值类型(struct),则不需要实例化它。如果是类,则必须实例化它,因为引用类型的默认值为null。

这段代码可以正常工作:

public struct LocationDetail 
{
    private string site;

    public string Site
    {
        get { return site; }
        set { site = value; }
    }
}

static void Main(string[] args)
{
    LocationResponse response = new LocationResponse();
    response.LocationDetails = new LocationDetail[4];
    response.LocationDetails[0].Site = "ABCDE";
    Console.Write(response.LocationDetails[0].Site);
}

2

可以把它看作是一个引用指针,如果你不初始化LocationDetail项目,就会得到一个 null 值。


2

它将每个元素设置为null,这是类的默认值,除非你另有规定。

C#如何自动实例化数组元素?也许你的数组类型甚至没有默认构造函数。也许在实际拥有它们之前,你不想消耗整个数组元素所需的内存。

我不认为运行时试图提前填充该数组有任何优势。


2
我把数组看作是鸡蛋盒。你可以声明一个鸡蛋盒,但这并不会把鸡蛋放在盒子里 - 你仍然需要决定将哪种类型的鸡蛋放在盒子的每个插槽中。有些可能想要彩蛋,而其他一些可能想要等级为 AA 的散养棕色鸡蛋。
数组本身不能提前知道你想要什么,因此默认不在插槽中放任何东西。

1

正如其他人所指出的那样,在您声明数组后,它将充满null。您可以通过执行以下操作来简化初始化逻辑:

response.LocationDetails = new LocationDetails [] {
    new LocationDetails(),
    new LocationDetails(),
    new LocationDetails(),
    new LocationDetails()
};

而更好的是,如果LocationDetails构造函数有一个带有siteid参数的重载就更好了:

response.LocationDetails = new LocationDetails [] {
    new LocationDetails("ABCDE"),
    new LocationDetails("FGHIJ"),
    new LocationDetails("KLMNO"),
    new LocationDetails("PQRST")
};

或者是Justice指出的超级花哨的C# 3.0东西 :)


1
response = new LocationResponse() {
    LocationDetails = new LocationDetail[] {
        new LocationDetail { site = "ABCDE" }
    }
}

1
这将是一个昂贵的操作,取决于创建对象所需做的工作。而且,如果对象不能简单地实例化怎么办?或者如果您需要一个给定类型的数组,其中只有一些字段最终包含一个对象,而其他字段应该为null呢?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接