2014-12-13 12 views
23

Rozważmy następujący:Tuple.Create() vs nowej krotki

Tuple<int, int> t1 = new Tuple<int,int>(1,2); 
Tuple<int, int> t2 = Tuple.Create(1,2); 

Czy jest jakaś różnica między tymi dwiema metodami tworzenia krotki? Z mojego czytania wynika, że ​​jest bardziej wygodnym skrótem niż cokolwiek, jak tworzenie obiektów w C++ (heap vs stack).

+2

'Tuple t1 = new Tuple (1,2);' <----- to jest powód, dla którego C# ma słowo kluczowe "var". –

Odpowiedz

0

Cóż, te pytania są stare ... ale mimo wszystko uważam, że mogę wnosić konstruktywny wkład. Z przyjętą odpowiedzi:

Przypuszczam jedną korzyścią jest to, że ponieważ nie trzeba określić typ z Tuple.Create można przechowywać anonimowych typów, dla których w przeciwnym razie nie byłyby w stanie powiedzieć, co typ jest

konsekwencją jest prawdziwe: można przechowywać anonimowych typów, dla których ...

Ale pierwsza część:

ponieważ nie trzeba określić t ype z Tuple.Create

nie zawsze jest prawdziwe.Rozważmy następujący scenariusz:

interface IAnimal 
{ 
} 

class Dog : IAnimal 
{ 
} 

Następujące nie skompilować:

Tuple<IAnimal> myWeirdTuple; 

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

Trzeba będzie podać parametr typu w metodzie Create jak ten:

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

która jako verbose pod nazwą new Tuple<IAnimal>(new Dog()) IMO

+0

W twoim przykładzie, nadal nie musisz określać typu podczas wywoływania 'Create ' - po prostu obsada Najpierw "Dog" do "IAnimal". 'Tuple.Create ((IAnimal) new Dog());' –

+0

Zgadza się, po prostu musisz przepisać słowo wewnątrz nawiasów ... Ta sama liczba znaków jak dotąd ... i (IAnimal) – taquion

+0

Don nie zrozum mnie źle, zgadzam się z twoją odpowiedzią. Ponieważ C# nie ma generycznych typów wnioskowania w konstruktorze, Tuple.Create został utworzony, ale nadal nie działa zawsze. W twoim kontrprzykładie nie przekazujesz już typu Psa, ale IAnimal. Wynika to z faktu, że cóż, C# nie zezwala na klasy kowariancji również – taquion

1

Nie ma różnicy. Jeśli spojrzeć na kod źródłowy, robi to samo.

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

Na przykład:

Tuple.create(1,2); 

zamierza zadzwonić

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

Nie ma już potrzeby łączenia z witrynami innych firm, utworzono program Microsoft [interfejs WWW dla źródła odniesienia] (http://referencesource.microsoft.com/#mscorlib/system/tuple.cs.9124c4bea9ab0199). –

15

Zaletą korzystania Tuple.Create() jest to, że nie koniecznie trzeba określić typy nowy Tuple tak jak z new Tuple<T1,T2>(*,*). Z pierwszej opcji, to jest ważne:

var newTuple = Tuple.Create(1,2); 
+0

Nie dotyczy wszystkich scenariuszy. Możesz zobaczyć moją odpowiedź. Pozdrowienia! – taquion

18

Osobiście uważam Tuple.Create() mniej gadatliwy i łatwiejsze do odczytania.

Nie ma różnicy, pod maską. W Tuple.Create() przeciążone metody to tylko kilka z metod statycznych, które nazywają się pierwsza wersja ty Wysłany:

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); 
    } 

    ... 

Przypuszczam jedną korzyścią jest to, że ponieważ nie trzeba określić typ z Tuple.Create można zapisać anonimowy typy, dla których inaczej nie byłbyś w stanie powiedzieć, jaki jest typ.

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); 

Stwarza to krotka z dwóch anonimowych typów, pierwszy jest new { string Name, DateTime BirthDate } a drugi jest new { int Height, string Name }.

Nadal nie jest zbyt wiele, co można z tym zrobić, ponieważ aby przekazać go innej metodzie, nadal trzeba będzie zdefiniować "typ" parametru. Tak naprawdę sprowadza się to do wygody.

+0

Ale dla mnie przypomina wzór Buildera, a ponieważ nie używa tego wzorca, wolę używać nowego słowa kluczowego –