Tuple.Create() vs new Tuple
Asked Answered
A

5

55

Consider the following expressions:

new Tuple<int,int>(1,2);

Tuple.Create(1,2);

Is there any difference between these two methods of Tuple creation? From my reading it seems to be more a convenient shorthand than anything like object creation in C++ (heap vs stack).

Amora answered 13/12, 2014 at 4:35 Comment(1)
Tuple<int, int> t1 = new Tuple<int,int>(1,2); <----- this is the reason why C# has the var keyword.Gault
D
15

Well, this questions is old... but nevertheless I think I may contribute constructively. From the accepted answer:

I suppose one benefit is that, since you don't have to specify the type with Tuple.Create, you can store anonymous types for which you otherwise wouldn't be able to say what the type is

The consequence is true: you can store anonymous types for which ...

But the first part:

since you don't have to specify the type with Tuple.Create

is not always true. Consider the following scenario:

interface IAnimal
{
}

class Dog : IAnimal
{
}

The following will not compile:

Tuple<IAnimal> myWeirdTuple;

myWeirdTuple = Tuple.Create(new Dog());

You will have to specify the type parameter in the Create method like this:

myWeirdTuple = Tuple.Create<IAnimal>(new Dog());

which is as verbose as calling new Tuple<IAnimal>(new Dog()) IMO

Development answered 25/7, 2017 at 15:8 Comment(3)
That´s right, you just have to rewrite the word inside the parenthesis ... Same amount of characters so far... <IAnimal> and (IAnimal)Development
Don't get me wrong, I agree with your answer. Since C# does not have generic type inference in constructor, Tuple.Create was created, but it still does not work always. In your counterexample you do not pass a Dog type anymore but a IAnimal. This is due to the fact that, well, C# does not allow covariant classes alsoDevelopment
Just for the record. Covariant class will be fine here since Tuple is immutableDevelopment
L
33

Personally, I find Tuple.Create() less verbose and easier to read.

There's no difference, under the hood. The Tuple.Create() overloaded methods are just a bunch of static methods that call the first version you posted:

public static class Tuple
{
    public static Tuple<T1> Create<T1>(T1 item1) {
        return new Tuple<T1>(item1);
    }

    public static Tuple<T1, T2> Create<T1, T2>(T1 item1, T2 item2) {
        return new Tuple<T1, T2>(item1, item2);
    }

    public static Tuple<T1, T2, T3> Create<T1, T2, T3>(T1 item1, T2 item2, T3 item3) {
        return new Tuple<T1, T2, T3>(item1, item2, item3);
    }

    ...

I suppose one benefit is that, since you don't have to specify the type with Tuple.Create, you can store anonymous types for which you otherwise wouldn't be able to say what the type is.

public class Person
{
    public string Name { get; set; }
    public int Height { get; set; }
    public DateTime BirthDate { get; set; }
}

var people = new List<Person>
{
    new Person { Name = "Bob", Height = 72, BirthDate = new DateTime(1984,1,1) },
    new Person { Name = "Mary", Height = 64, BirthDate = new DateTime(1980,2,2) }
};

var oneAnonList = people.Select(x => new { x.Name, x.BirthDate });
var twoAnonList = people.Select(x => new { x.Height, x.Name });

var myTuple = Tuple.Create(oneAnonList, twoAnonList);

This creates a Tuple with two anonymous types, the first is a new { string Name, DateTime BirthDate } and the second is a new { int Height, string Name }.

There's still not too terribly much you can do with that, since to pass it to another method, you'd still need to be able to define the "type" of the parameter. So it really comes down to convenience.

Leprosarium answered 13/12, 2014 at 4:43 Comment(1)
But to me it reminds of the Builder pattern and since it is not using that pattern, I prefer to use the new keywordLozano
M
23

The benefit of Tuple.Create is that you can usually omit the type arguments, eg. Tuple.Create(1,2) is briefer than new Tuple<int,int>(1,2).

If you try omitting the type arguments from the constructor new Tuple(1,2) you will see error CS0712 "Cannot create an instance of the static class 'Tuple""

Multivibrator answered 13/12, 2014 at 4:43 Comment(1)
No true for all scenarios. You can see my answer. Regards!Development
C
16

Starting with C# 7, you can now simply declare Value Tuple like so:

var unnamed = (1, 2);

or

var named = (name: "Joe", age: 2);

See microsoft documentation here: https://learn.microsoft.com/en-us/dotnet/csharp/tuples

Colic answered 3/12, 2019 at 14:26 Comment(0)
D
15

Well, this questions is old... but nevertheless I think I may contribute constructively. From the accepted answer:

I suppose one benefit is that, since you don't have to specify the type with Tuple.Create, you can store anonymous types for which you otherwise wouldn't be able to say what the type is

The consequence is true: you can store anonymous types for which ...

But the first part:

since you don't have to specify the type with Tuple.Create

is not always true. Consider the following scenario:

interface IAnimal
{
}

class Dog : IAnimal
{
}

The following will not compile:

Tuple<IAnimal> myWeirdTuple;

myWeirdTuple = Tuple.Create(new Dog());

You will have to specify the type parameter in the Create method like this:

myWeirdTuple = Tuple.Create<IAnimal>(new Dog());

which is as verbose as calling new Tuple<IAnimal>(new Dog()) IMO

Development answered 25/7, 2017 at 15:8 Comment(3)
That´s right, you just have to rewrite the word inside the parenthesis ... Same amount of characters so far... <IAnimal> and (IAnimal)Development
Don't get me wrong, I agree with your answer. Since C# does not have generic type inference in constructor, Tuple.Create was created, but it still does not work always. In your counterexample you do not pass a Dog type anymore but a IAnimal. This is due to the fact that, well, C# does not allow covariant classes alsoDevelopment
Just for the record. Covariant class will be fine here since Tuple is immutableDevelopment
T
8

There is no difference. If you take a look at the source code, it is doing the same thing.

http://referencesource.microsoft.com/#mscorlib/system/tuple.cs,9124c4bea9ab0199

For example:

Tuple.create(1,2); 

is going to call

public static Tuple<T1, T2> Create<T1, T2>(T1 item1, T2 item2) {
    return new Tuple<T1, T2>(item1, item2);
}
Tyrolienne answered 13/12, 2014 at 4:43 Comment(1)
There is no need to link to 3rd party sites anymore, microsoft created a web interface for the reference source.Kwang

© 2022 - 2024 — McMap. All rights reserved.