-1

My goal is to create a List of pairs (of ONLY type double). For example: { {1.0,1.1}, {1.2,1.3}, {1.4,1.5}, {...}, {...} } where {1.0,1.1} is List[0], {1.2,1.3} is List[1], {1.4,1.5} is List[2], et cetera.

RATION ERROR

              Tuple<double,double> a1 = new Tuple<double,double>(1.0, 1.1);

              Tuple<double,double> a2 = new Tuple<double,double>(1.2, 1.3);

              Tuple<double,double> a3 = new Tuple<double,double>(1.4, 1.5);

            //List< Tuple<double,double> >  a4 = new List< Tuple<double, double> >(a1, a2, a3);      //ERROR

              List< Tuple<double,double> >  a5 = new List< Tuple<double, double> >{a1, a2, a3};  //COMPILES

              List< Tuple<double,double> >  a6 = new List< Tuple<double, double> >(){a1, a2, a3};    //COMPILES

            //List< Tuple<double,double> >  a7 = new List< Tuple<double, double> >{a1, a2, a3}();    //ERROR
  1. In a4, a5, a6, and a7, why are the () optional but the {} are not?
  2. In a4, why can I not use () for instantiating the List<>, considering the () is made for instantiation arguments?
  3. Does 2. have the same reasoning as the error when trying to instantiate a7?

I know that [] always indicates selecting an element in an array, hence why I didn't try that.

Also, I am aware of ValueTuple but I want compatibility with previous versions of C# and/or .NET (idk the difference) and Tuple is not significantly more amazing than ValueTuple.

5
  • 2
    I think the collection initializers documentation and the list constructors documentation should address both of your questions. Commented Jul 15, 2022 at 0:52
  • Note the absence of a constructor that accepts params T[] items (params documentation). With that in mind, how would new List<Tuple<double, double>>(a1, a2, a3) ever work? Commented Jul 15, 2022 at 0:55
  • The cat example halfway down the page on the first link really helped! Thank you! The second link didn't really help me understand anything but the Collection methods TrimExcess() and Insert(). a0 was supposed to declare without instantiating, but I guess that isn't allowed like it is for primitives like "int a;" Commented Jul 15, 2022 at 1:08
  • "The second link didn't really help me understand anything" - OK, so you're asking why you can't do new List<Tuple<double, double>>(a1, a2, a3) (or whatever items). There is no constructor that takes items in this format. Commented Jul 15, 2022 at 1:09
  • Ah, I suppose I was associating functions with constructors... For example Func(someType someVar); Commented Jul 15, 2022 at 1:12

1 Answer 1

2

When you use { a1, a2, a3 } you're using the collection initializer. In this situation, you don't necessarily have to add () to call the parameterless constructor of the collection. That's why new List<int>() { 1 } would work just as well as new List<int> { 1 }.

A more complex example might be to specify the initial capacity (not number of items) of the list, and add fewer items: new List<int>(5) { 1, 2, 3 }. This would give us a list with 3 items in it, but with a capacity of 5 (so it doesn't need to internally resize its arrays until we try to add a 6th item).

As for why new List<int>(1, 2, 3) wouldn't work: there simply isn't a constructor that accepts items in this format.

Consider these two methods:

public static void Test1(int[] items)
{
}

public static void Test2(params int[] items)
{
}

We can call Test1 as Test1(new int[] { 1, 2, 3 }) but not as Test1(1, 2, 3). Because Test2 has the params keyword, we can call it both as Test2(new int[] { 1, 2, 3 }) and Test2(1, 2, 3). It's the params keyword that does the magic here.

Now, the following list constructors are available:

  • public List (); - this doesn't take any parameters, and is what we use when we write new List<int> { 1 } (implicit) or new List<int>() { 1 } (explicit).
  • public List (System.Collections.Generic.IEnumerable<T> collection); - this allows you to pass any object that implements IEnumerable<T>. This is why new List<int>(new int[] { 1, 2, 3 }) works. Arrays (int[]) implement IEnumerable<T>, as do lists, queues, dictionaries, and all sorts of other collection types.
  • public List (int capacity); - This just sets the capacity, and is what we use if we call new List<int>(5) { 1, 2, 3 };

There is no constructor that accepts params T[], so we simply can't construct a list like new List<int>(1, 2, 3);.

Documentation:

Sign up to request clarification or add additional context in comments.

Comments

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.