0

I want to ensure that my List can contain only 2 elements array of int. I am currently have to declare a struct but I really don't want to declare many type if it is not really necessary. So I am wondering if I can declare a list of fixed size array.

    static void Main(string[] args)
    {
        //I want to declare something like this
        List<int[2]> list = new List<int[2]>();
        
        list.Add(new int[2] { 1, 2 });
        list.Add(new int[2] { 3, 4 });

        //What I having to do(not really want because I have to declare struct)
        List<TwoElement> list2 = new List<TwoElement>();
        list2.Add(new TwoElement() { Element1 = 1, Element2 = 2 });
        list2.Add(new TwoElement() { Element1 = 1, Element2 = 2 });
    }

    private struct TwoElement
    {
        public int Element1;
        public int Element2;
    }
Nam Pham
  • 73
  • 1
  • 5
  • Question which can help you https://stackoverflow.com/questions/466946/how-to-initialize-a-listt-to-a-given-size-as-opposed-to-capacity – Паша Мороз Dec 17 '20 at 03:25
  • 1
    Create a class (say `class ArrayOf2Int`) that contains an array of int. Make the class behave like an array (mostly), but restrict it to only having two integers. You may find it's easier just to have it contain two integers. Whatever you do, give it a type signature as close as possible to `int[]` – Flydog57 Dec 17 '20 at 04:30

2 Answers2

0

It's not possible, as reference from this post, in short, int[2] is not a Type, therefore no way to limit it without a struct, model or tuple.

I will prefer using tuple in this case, since it's pretty simple with lambda

List<(int, int)> list = new List<(int, int)>();
list.Add((1, 1));
list.Add((2, 3));
Tấn Nguyên
  • 1,607
  • 4
  • 15
  • 25
  • 2
    Note to OP, a ValueTuple ***is*** a struct, and as apposed to using an array they are copied and created every time you use or update them and have all the subtleties of any other value type (which may or may not worry you)... – TheGeneral Dec 17 '20 at 04:04
0

Here's an idea of a fixed length array. If the length was more than 2, then I'd probably have a private int[] theArray member. But, at two, it probably makes sense to have a _first and a _second member the way I show. The System.Array class has a lot of members - you get to implement the ones you care about (I put all the Properties in (either as a property or as a const)).

In any case, it gives you an idea of a possible solution:

public class ArrayOf2Int : IEnumerable<int>
{
    private readonly int _first;
    private readonly int _second;

    //I had the urge to make this a Lazy<object> - but it's an object, who cares
    //If you implement this with an array of int (int[]) instead of two ints, delegate this to the SyncRoot of the array
    public object SyncRoot { get; } = new object();

    public const int Length = 2;
    public const long LongLength = 2;
    public const int Rank = 1;
    public const bool IsFixedSize = true;
    public const bool IsSynchronized = false;

    public ArrayOf2Int(int first, int second)
    {
        _first = first;
        _second = second;
    }

    public int this[int i]
    {
        get
        {
            if (i < 0 || i > 1)
            {
                throw new ArgumentOutOfRangeException(nameof(i), "Index out of range");
            }

            return i == 0 ? _first : _second;
        }
    }
    public IEnumerator<int> GetEnumerator()
    {
        yield return _first;
        yield return _second;
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
Flydog57
  • 6,851
  • 2
  • 17
  • 18