使用默认构造函数初始化数组

发布于 2024-10-15 02:18:53 字数 388 浏览 7 评论 0原文

public class Sample
{
     static int count = 0;
     public int abc;
     public Sample()
     {
        abc = ++Sample.count;
     }
}

我想创建一个上述类的数组,并希望通过调用默认构造函数来初始化数组中的每个元素,以便每个元素可以有不同的 abc。所以我这样做了:

Sample[] samples = new Sample[100];

但这并不不做我认为应该做的事。看来默认构造函数没有被调用。创建数组时如何调用默认构造函数?

我也想知道上面的语句有什么作用?

public class Sample
{
     static int count = 0;
     public int abc;
     public Sample()
     {
        abc = ++Sample.count;
     }
}

I want to create an array of above class, and want each element in the array to be initialized by invoking the default constructor, so that each element can have different abc.So I did this:

Sample[] samples = new Sample[100];

But this doesn't do what I think it should do. It seems this way the default constructor is not getting called. How to invoke default constructor when creating an array?

I also would like to know what does the above statement do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

童话里做英雄 2024-10-22 02:18:53

基本上你不能。当您创建数组时,它总是最初填充类型的默认值 - 对于类而言,该默认值始终是空引用。对于 int 来说,它是 0,对于 bool 来说,它是 false,等等。

(如果您使用数组初始值设定项,这将创建“空”数组,然后然后 当然,用您指定的值填充它。)

通过调用构造函数来填充数组的方法有多种 - 我自己可能只使用 foreach 循环。将 LINQ 与 Enumerable.Range/Repeat 结合使用感觉有点强迫。

当然,您始终可以编写自己的填充方法,甚至作为扩展方法:

public static T[] Populate<T>(this T[] array, Func<T> provider)
{
    for (int i = 0; i < array.Length; i++)
    {
        array[i] = provider();
    }
    return array;
}

然后您可以使用:

Sample[] samples = new Sample[100].Populate(() => new Sample());

我喜欢这个解决方案的地方:

  • 它仍然是一个单一的表达式,在各种场景中都很有用
  • 它不会引入您实际上不需要的概念(例如重复单个值或创建范围)

当然您可以添加更多选项:

  • 采用 Func 代替的重载Func 的,将索引传递给提供者
  • 创建数组并填充它的非扩展方法

You can't, basically. When you create an array, it's always initially populated with the default value for the type - which for a class is always a null reference. For int it's 0, for bool it's false, etc.

(If you use an array initializer, that will create the "empty" array and then populate it with the values you've specified, of course.)

There are various ways of populating the array by calling the constructor - I would probably just use a foreach loop myself. Using LINQ with Enumerable.Range/Repeat feels a little forced.

Of course, you could always write your own population method, even as an extension method:

public static T[] Populate<T>(this T[] array, Func<T> provider)
{
    for (int i = 0; i < array.Length; i++)
    {
        array[i] = provider();
    }
    return array;
}

Then you could use:

Sample[] samples = new Sample[100].Populate(() => new Sample());

What I like about this solution:

  • It's still a single expression, which can be useful in various scenarios
  • It doesn't introduce concepts you don't actually want (like repeating a single value or creating a range)

Of course you could add more options:

  • An overload which takes a Func<int, T> instead of a Func<T>, passing the index to the provider
  • A non-extension method which creates the array and populates it
铁轨上的流浪者 2024-10-22 02:18:53

您的代码仅创建数组,但不创建其中的任何项目。基本上,您需要将 Sample实例存储到此数组中。

简而言之,没有任何花哨的 LINQ 等:

Sample[] samples = new Sample[100];
for (int i = 0; i < samples.Length; i++) samples[i] = new Sample();

另请注意,您的解决方案不是线程安全的。

Your code creates only the array, but neither of its items. Basically, you need to store instances of Sample into this array.

To put it simple, without any fancy LINQ etc.:

Sample[] samples = new Sample[100];
for (int i = 0; i < samples.Length; i++) samples[i] = new Sample();

Please also note your solution is not thread-safe.

假情假意假温柔 2024-10-22 02:18:53

没有办法自动执行此操作;数组初始化本质上就是“将这块内存擦除为0”。你必须做类似的事情:

var arr = new SomeType[size];
for(int i = 0 ; i < size ; i++) arr[i] = new SomeType();

There is no way to do this automatically; array initialization is essentially "wipe this block of memory to 0s". You would have to do something like:

var arr = new SomeType[size];
for(int i = 0 ; i < size ; i++) arr[i] = new SomeType();
最终幸福 2024-10-22 02:18:53

这是另一个不需要任何扩展方法的单行:

Sample[] array = Enumerable.Range(0, 100).Select(i => new Sample()).ToArray();

另一个不错的选择是 Scott 的对乔恩的回答的建议:

public static T[] Populate<T>(this T[] array) 
    where T : new()
{
    for (int i = 0; i < array.Length; i++)
        array[i] = new T();
    return array;
}

所以你可以这样做:

Sample[] array = new Sample[100].Populate();

Here is another one-liner that doesn't require any extension method:

Sample[] array = Enumerable.Range(0, 100).Select(i => new Sample()).ToArray();

Another nice option is Scott's suggestion to Jon's answer:

public static T[] Populate<T>(this T[] array) 
    where T : new()
{
    for (int i = 0; i < array.Length; i++)
        array[i] = new T();
    return array;
}

So you can do:

Sample[] array = new Sample[100].Populate();
多孤肩上扛 2024-10-22 02:18:53

此时你有一个大小为 100 的空数组,如果你想用项目填充它,那么你必须执行以下操作:

for(int i=0; i<samples.Length; i++) {
   samples[i] = new Sample();
}

At this point you have an empty array of size 100, if you want to fill it with items, then you would have to do something like:

for(int i=0; i<samples.Length; i++) {
   samples[i] = new Sample();
}
两人的回忆 2024-10-22 02:18:53

问题在于,通过声明该数组,您从未为每个对象分配空间。您仅仅为 100 个 Sample 类型的对象分配了空间。您必须自己调用每个构造函数。

详细说明:

Food[] foods = Food[100];
for (int k = 0; k < foods.length; k++) {
   foods[k] = new Food();
}

一个有趣的解决方法可能是工厂函数。考虑将其附加到您的 Sample 类中。

public static Sample[] getInstances(int aNumber) {
    Sample[] sample = Sample[aNumber];
    for (int k = 0; k < sample.length; k++) {
       sample[k] = new Sample();
    }

    return sample;
}

隐藏一点瑕疵 - 前提是这对您来说是一个有用的功能。

The problem is that by declaring that array, you never allocated space for each object. You merely allocated space for 100 objects of type Sample. You'll have to call the constructor on each yourself.

To elaborate:

Food[] foods = Food[100];
for (int k = 0; k < foods.length; k++) {
   foods[k] = new Food();
}

An interesting work around might be a factory function. Consider attaching this to your Sample class.

public static Sample[] getInstances(int aNumber) {
    Sample[] sample = Sample[aNumber];
    for (int k = 0; k < sample.length; k++) {
       sample[k] = new Sample();
    }

    return sample;
}

Hides the blemish, a bit - providing this is a useful function to you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文