0

I have class Cat and it has one attribute Name and one method SayMiau, I want to create an array of Cats with 10 instances which have different names like cat1 cat2 and etc and later in a loop call the method SayMiau for all of them in a loop.

Cat[] cats = new Cat[10];

int id = 1;

foreach(Cat cat in cats){
    cat.Name = $"Cat{id}";
    id ++;
}

foreach(Cat cat in cats){
    cat.SayMiau(cat.Name);
}

class Cat{
    public string? Name;

    public static void SayMiau(string name){
        Console.WriteLine("Cat{0} said Miauuuuu!",name);
    }
}
3
  • 1
    You don't need string? and you don't need static. And SayMiau() doen't need the name then, because the cat already knows her name. Commented Sep 22, 2022 at 8:05
  • If SayMiau will not be static, you will not have to pass name as a parameter (you'll be able to use Name field). Commented Sep 22, 2022 at 8:06
  • You explain what you want to do, but there is no clear question in your text. What are you expecting from us. Please focus on one programming problem Commented Sep 22, 2022 at 8:18

2 Answers 2

4

You haven't really explained your problem, but I can assume what it is from your code.

Here:

Cat[] cats = new Cat[10];

You define an array of Cats. But this is not what you think it is. All you are actually doing is saying that your array will contain a maximum of 10 objects of type Cat, but each element in the array is still null (albeit of type Cat). There are no Cat instances inside it at this stage and you still need to initialise and add them into the array individually.

so then here:

foreach(Cat cat in cats){
    cat.Name = $"Cat{id}";
    id ++;
}

You are trying to assign values to each Cat in your array. But as said, the Array doesn't yet have any Cat instances, so you are trying to add values to nothing, which doesn't work.

Also, a foreach statement uses an immutable collection, meaning that you can't amend values within the list. So you can't create a new Cat object within this loop. So you need to use a for loop instead.

So you should have

Cat[] cats = new Cat[10];

int id = 1;

for(int ind = 0; ind < cats.Length; ind++){
    Cat cat = new Cat();
    cat.Name = $"Cat{id}";
    id ++;
    cats[ind] = cat;
}

Also, the SayMiau method needs amending.
You need to remove static, and remove the signature. It is a Class method so no static needed and it should use the Name value within the class, not have it passed. So it should be

class Cat
{
    public string? Name;

    public void SayMiau()
    {
        Console.WriteLine("Cat{0} said Miauuuuu!", Name);
    }
}

Then your calling statement should be

    foreach (Cat cat in cats)
    {
        cat.SayMiau();
    }
Sign up to request clarification or add additional context in comments.

10 Comments

"but it is an empty array" - this is not accurate. The array is not empty. It will contain exactly 10 elements of class Cat. But you are right that Cat being a reference type requires an additional allocation per instance (otherwise the array element will hold null).
@wohlstad "contain elements of class" is not really true, because what is "class" in your statement? Like you say, Cat is a reference type, so the array will only reserve space for 10 references (and requires those to be of type Cat). The allocation of the objects of type Cat still has to be done separately.
Side note: we can get rid of ind in the for loop by using loop variable: cat.Name = $"Cat{i + 1}";
@wohlstad Yes, I didn't make this clear. I have updated the text to try to improve this description.
@wohlstad well, null is not Cat. Just try with the is operator. null is Cat will give false. Same for the elements of the array when they are empty. The only guarantee it gives, is that you can only assign a reference to an object of type Cat (or null) to the array elements.
|
0

You can try to use Linq to initialize the array with values needed.

Example

var emptyCats = new Cat[10]; // array with 10 *empty* elements
var cats = emptyCats.Select((_, i) => new Cat { Name = $"Cat{i}" }); // go throug the array and transform it to initialized array

foreach (Cat cat in cats)
 {
    Cat.SayMiau(cat.Name); // miau
 }

Explanation

The idea is pretty simple. You created an empty array and now just need to transform it to another, filled array. Select takes a function that do exactly this. It transform one elment into any other element. So I passed a function that initialize an instance of the Cat class.

As a result - we have list of filled cats :)

7 Comments

Curious. Apart from the more complex to read syntax, why the -1?
Because OP doesn't learn anything from this answer. They don't understand where there thinking goes wrong, they can't get the basic concepts right and instead are introduced to an even more complex topic which they will understand even less. That's why @Marco
That's a reasoning I can agree with. Just wanted to know. @ThomasWeller
Guys, you are too fast for me :) However I can agree only with that part about no explanations. The projections is not that complex topic to be avoided here.
Combine this with Enumerable.Range and you don't even need to allocate the empty array. (Nor the special overload of Select). And of course remove the static from saymiau, so you can just use the property.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.