tzippy
tzippy

Reputation: 6638

Array as property. Looking for simpler way to fill an array

I am pretty new to C# and I see a lot of code where I'm not quite familiar with the syntax. So I was wondering if there's some simpler way of doing what I did here:

I have a class with various properties and functions. One of them is public int gettypeforitem(int i) which returns an integer. I want to define a property of type int[] that returns an array of the types of all items.

I come from C++, so the following code seems logic to me, but I was wondering if there's a more "straight forward" way in doing this in C#. Thank you!

public int[] type
{
      get
      {
            List<int> _list = new List<int>();
            for(uint i=0; i<NumberOfItems;i++)
               _list.Add(gettypeforitem(i));
            return _list.ToArray();
      }
}

Upvotes: 3

Views: 658

Answers (4)

serhiyb
serhiyb

Reputation: 4833

public int[] type
{
    get
    {
         return Enumerable.Range(0, NumberOfItems).Select(gettypeforitem).ToArray();
    }
}

Update: As suggested in comments its better to keep C# naming standards:

public int[] Types
{
    get
    {
         return Enumerable.Range(0, NumberOfItems).Select(getTypeForItem).ToArray();
    }
}

Upvotes: 13

A.B.
A.B.

Reputation: 2470

Does the return type of the property have to be really an array? If not, you can alternatively also use this:

public IEnumerable<int> type
{
      get
      {
            for(uint i=0; i<NumberOfItems;i++)
               yield return gettypeforitem(i);
      }
}

and then:

myObject.type.ToArray();

Upvotes: 2

Jon Skeet
Jon Skeet

Reputation: 1499800

LINQ is the way forward here, I'd say:

public int[] Types => Enumerable.Range(0, NumberOfItems)
                                .Select(i => GetTypeForItem(i))
                                .ToArray();

I've changed the names to follow .NET naming conventions, and this is using C# 6's expression-bodied property syntax.

As this is doing a relatively large amount of work for a property - generating a new array every call, for a start - you might want to consider making it a method instead:

public int[] GetTypes() => Enumerable.Range(0, NumberOfItems)
                                     .Select(i => GetTypeForItem(i))
                                     .ToArray();

As noted in comments elsewhere, you may be able to use a method group conversion for the argument to the Select method:

public int[] GetTypes() => Enumerable.Range(0, NumberOfItems)
                                     .Select(GetTypeForItem)
                                     .ToArray();

The exact rules for when method group conversions are valid as arguments always elude me, so I won't try to summarise them here. (They've changed over time, too.)

Upvotes: 20

Patrick Hofman
Patrick Hofman

Reputation: 156918

Since you know the number of items, you can create an array straight away:

int[] _arr = new int[NumberOfItems];
for(uint i=0; i<NumberOfItems;i++)
    _arr[i] = gettypeforitem(i);
return _arr;

Or if you don't care about the overhead:

Enumerable.Range(0, NumberOfItems).Select(gettypeforitem).ToArray();

Upvotes: 3

Related Questions