Praktyczny przykład zastosowania Tuple w .Net 4.0?
97
Widziałem Tuple wprowadzony w .Net 4, ale nie jestem w stanie sobie wyobrazić, gdzie można go użyć. Zawsze możemy stworzyć klasę niestandardową lub strukturę.
Może to dobre miejsce, aby zauważyć, że ten temat jest bardzo stary. Zobacz, co się stało w C # 7 !
maf-soft
Odpowiedzi:
83
O to właśnie chodzi - wygodniej jest nie tworzyć niestandardowej klasy lub struktury przez cały czas. Jest to ulepszenie Actionlub Func... możesz samemu tworzyć te typy, ale wygodnie jest, aby istniały w ramach.
Prawdopodobnie warto zwrócić uwagę na MSDN : „Wszystkie publiczne statyczne elementy członkowskie tego typu są bezpieczne dla wątków. Nie ma gwarancji, że żadne elementy członkowskie instancji będą bezpieczne dla wątków. ”
Matt Borja,
Cóż, może więc projektanci języków powinni byli ułatwić tworzenie niestandardowych typów w locie? Więc moglibyśmy zachować tę samą składnię zamiast wprowadzać kolejną?
Thomas Eyde
@ThomasEyde, czyli dokładnie to, co robili przez ostatnie 15 lat. W ten sposób dodano elementy z treścią wyrażenia, które teraz cenią krotki. Klasy rekord stylu wąsko brakowało plecy cięcia w sierpniu (9 miesięcy przed upływem tego komentarza) dla tej wersji C # 7, i są prawdopodobnie wychodzi w C # 8. Należy również pamiętać, że wartość krotki oferują równości wartość gdzie zwykły starych klas nie . Wprowadzenie tego wszystkiego w 2002 roku wymagałoby przewidywania
Panagiotis Kanavos
co masz na myśli przez convenient not to make a custom class. Czy masz na myśli tworzenie niestandardowej instancji klasy za pomocą =new..()?
Alex
75
Dzięki krotkom można łatwo zaimplementować słownik dwuwymiarowy (lub n-wymiarowy, jeśli o to chodzi). Na przykład możesz użyć takiego słownika, aby zaimplementować mapowanie wymiany walut:
Wolałbym raczej używać Enum dla skrótów krajów. Czy to jest możliwe?
Zack
1
Jasne, powinno działać bez problemów, ponieważ wyliczenia są typami wartości.
MarioVW
@MarioVW Można to również osiągnąć za pomocą wielowymiarowej tablicy. Jak krotka ma znaczenie?
Alex
26
W magazynie MSDN jest doskonały artykuł, który mówi o bólach brzucha i kwestiach projektowych, które doprowadziły do dodania Tuple do BCL. Szczególnie interesujący jest wybór między typem wartości a typem referencyjnym.
Jak wyjaśnia artykuł, siłą napędową Tuple było tak wiele grup wewnątrz firmy Microsoft, które miały z tego pożytek, zespół F # z przodu. Chociaż nie zostało to wspomniane, uważam, że nowe słowo kluczowe „dynamiczne” w C # (i VB.NET) również miało z tym coś wspólnego, krotki są bardzo powszechne w językach dynamicznych.
Poza tym tworzenie własnego poco nie jest szczególnie lepsze, przynajmniej możesz nadać członkom lepszą nazwę.
AKTUALIZACJA: w związku z dużą rewizją w C # wersji 7, teraz otrzymuję dużo więcej miłości do składni. Wstępne ogłoszenie w tym poście na blogu .
Oto mały przykład - załóżmy, że masz metodę, która musi wyszukać uchwyt użytkownika i adres e-mail, biorąc pod uwagę identyfikator użytkownika. Zawsze możesz utworzyć niestandardową klasę, która zawiera te dane, lub użyć parametru ref / out dla tych danych, lub możesz po prostu zwrócić krotkę i mieć ładną sygnaturę metody bez konieczności tworzenia nowego POCO.
Jest to jednak dobry przykład, który nie uzasadnia używania Tuple.
Amitabh
7
Krotka jest tutaj przyzwoicie dopasowana, ponieważ zwracasz różne wartości; ale krotka świeci bardziej, gdy zwracasz wiele wartości różnych typów .
Mark Rushakoff
21
Innym dobrym przykładem może być int.TryParse, ponieważ można wyeliminować parametr wyjściowy i zamiast tego użyć krotki. Więc możesz mieć Tuple<bool, T> TryParse<T>(string input)i zamiast używać parametru wyjściowego, otrzymujesz obie wartości z powrotem w krotce.
Tejs
3
w rzeczywistości dokładnie to się dzieje, gdy wywołujesz dowolną metodę TryParse z F #.
classGrid{publicstaticint[,]Cells={{08,02,22,// whole grid omittedpublicstaticIEnumerable<Tuple<int,int,int,int>>ToList(){// code converts grid to enumeration every possible set of 4 per rules// code omitted}}
Składnia krotki w języku C # jest absurdalnie obszerna, więc deklarowanie krotek jest trudne. I nie ma dopasowywania wzorców, więc są również bolesne w użyciu.
Ale czasami potrzebujesz tylko grupowania obiektów ad hoc bez tworzenia dla niego klasy. Na przykład, powiedzmy, że chciałem zagregować listę, ale chciałem mieć dwie wartości zamiast jednej:
// sum and sum of squares at the same timevar x =Enumerable.Range(1,100).Aggregate((acc, x)=>Tuple.Create(acc.Item1+ x, acc.Item2+ x * x));
Zamiast łączyć zbiór wartości w jeden wynik, rozwińmy pojedynczy wynik do zbioru wartości. Najłatwiejszym sposobem zapisania tej funkcji jest:
fkonwertuje stan na krotkę. Zwracamy pierwszą wartość z krotki i ustawiamy nasz nowy stan na drugą wartość. To pozwala nam zachować stan podczas obliczeń.
Używasz go jako takiego:
// return 0, 2, 3, 6, 8var evens =Unfold(0, state => state <10?Tuple.Create(state, state +2):null).ToList();// returns 0, 1, 1, 2, 3, 5, 8, 13, 21, 34var fibs =Unfold(Tuple.Create(0,1), state =>Tuple.Create(state.Item1,Tuple.Create(state.Item2, state.Item1+ state.Item2))).Take(10).ToList();
evensjest dość prosty, ale fibsjest trochę sprytniejszy. W staterzeczywistości jest to krotka, która zawiera odpowiednio fib (n-2) i fib (n-1).
+1 Tuple.Create jest przydatnym skrótem dlanew Tuple<Guid,string,...>
AaronLS,
@Juliet Jakie użycie słowa kluczowego State
irfandar
7
Nie podoba mi się ich nadużywanie, ponieważ tworzą kod, który nie wyjaśnia samego siebie, ale są niesamowite w implementacji kluczy złożonych w locie, ponieważ implementują IStructuralEquatable i IStructuralComparable (do użycia zarówno do wyszukiwania, jak i porządkowania cele).
I łączą wewnętrznie hashcody wszystkich swoich elementów; na przykład tutaj jest GetHashCode Tuple (pobrane z ILSpy):
Krotki doskonale nadają się do wykonywania wielu asynchronicznych operacji we / wy na raz i zwracania wszystkich wartości razem. Oto przykłady robienia tego z Tuple i bez. Krotki mogą faktycznie uczynić twój kod bardziej przejrzystym!
Jeśli korzystasz z funkcji anonimowego typu domniemanych zresztą wtedy nie robią kod mniej jasna za pomocą krotka. Ponowne dostrojenie krotki z metody? Moim skromnym zdaniem używaj oszczędnie, gdy klarowność kodu jest kluczowa. Wiem, że programowaniu funkcjonalnemu w C # trudno się oprzeć, ale musimy wziąć pod uwagę tych wszystkich starych, niezgrabnych programistów C # zorientowanych obiektowo.
Krotki są intensywnie używane w językach funkcjonalnych, które mogą robić z nimi więcej rzeczy, teraz F # jest „oficjalnym” językiem .net, z którym można współpracować z C # i przekazywać je między kodem napisanym w dwóch językach.
Krotki są również wbudowane w typy dla niektórych popularnych języków skryptowych, takich jak Python i Ruby (które mają również implementacje .Net dla interop ... IronPython / Ruby).
MutantNinjaCodeMonkey
5
Zwykle unikam Tuplew większości scenariuszy, ponieważ szkodzi to czytelności. Jest to jednak Tupleprzydatne, gdy trzeba pogrupować niepowiązane dane.
Na przykład załóżmy, że masz listę samochodów i miast, w których zostały zakupione:
Tuplejest równie przydatny w sytuacjach krytycznych, jak Pointlub SomeVectormoże być przydatny podczas wykonywania operacji graficznych. Podkreśla dwie wartości, które są ze sobą bardzo powiązane. Często widzę właściwości o nazwach StartTime i EndTime podczas czytania kodu, ale nawet lepiej niż data, godzina i czas trwania, krotka zmusza cię do rozważenia obu wartości za każdym razem, gdy działasz w tym obszarze logiki biznesowej. Lub zwracanie „hej, dane się zmieniły (bool), oto dane (inny typ)” w ciężkim przetwarzaniu zamiast przechodzenia przez intensywne powiązania.
Léon Pelletier
3
Powinieneś być bardzo ostrożny podczas używania Tuplei prawdopodobnie dwa razy pomyśleć, zanim to zrobisz. Z mojego wcześniejszego doświadczenia dowiedziałem się, że używanie Tuplebardzo utrudnia czytanie i obsługę kodu w przyszłości. Jakiś czas temu musiałem naprawić kod, w którym krotki były używane prawie wszędzie. Zamiast myśleć o odpowiednich modelach obiektowych, używali po prostu krotek. To był koszmar ... czasami chciałem zabić gościa, który napisał kod ...
Nie chcę mówić, że nie powinieneś używać Tuplei to jest złe czy coś i jestem w stu procentach pewien, że są zadania, w których Tuplejest najlepszym kandydatem do użycia, ale prawdopodobnie powinieneś się jeszcze raz zastanowić, czy NAPRAWDĘ tego potrzebujesz ?
Najlepszym zastosowaniem dla krotek, które znalazłem, jest zwrócenie więcej niż jednego typu obiektu z metody, wiesz, jakie będą typy obiektów i liczba, i nie jest to długa lista.
Właśnie znalazłem rozwiązanie jednego z moich problemów w Tuple. Jest to podobne do deklarowania klasy w zakresie metody, ale z leniwym deklarowaniem nazw jej pól. Operujesz na kolekcjach krotek, ich pojedynczych wystąpieniach, a następnie na podstawie swojej krotki tworzysz kolekcję typu anonimowego z wymaganymi nazwami pól. Pozwala to uniknąć tworzenia nowej klasy w tym celu.
Zadaniem jest napisanie odpowiedzi JSON z LINQ bez żadnych dodatkowych klas:
//I select some roles from my ORM my with subrequest and save results to Tuple listvar rolesWithUsers =(from role in roles
selectnewTuple<string,int,int>(
role.RoleName,
role.RoleId,
usersInRoles.Where(ur => ur.RoleId== role.RoleId).Count()));//Then I add some new element required element to this collectionvar tempResult = rolesWithUsers.ToList();
tempResult.Add(newTuple<string,int,int>("Empty",-1,
emptyRoleUsers.Count()));//And create a new anonimous class collection, based on my Tuple list
tempResult.Select(item =>new{GroupName= item.Item1,GroupId= item.Item2,Count= item.Item3});//And return it in JSONreturnnewJavaScriptSerializer().Serialize(rolesWithUsers);
Oczywiście moglibyśmy to zrobić deklarując nową klasę dla moich grup, ale pomysł stworzenia takich anonimowych kolekcji bez deklarowania nowych klas.
Cóż, w moim przypadku musiałem użyć krotki, gdy dowiedziałem się, że nie możemy użyć parametru out w metodzie asynchronicznej. Przeczytaj o tym tutaj . Potrzebowałem też innego typu zwrotu. Więc zamiast tego użyłem krotki jako mojego typu zwracanego i oznaczyłem metodę jako asynchroniczną.
Przykładowy kod poniżej.
......// calling code.var userDetails =awaitGetUserDetails(userId);Console.WriteLine("Username : {0}", userDetails.Item1);Console.WriteLine("User Region Id : {0}", userDetails.Item2);......privateasyncTuple<string,int>GetUserDetails(int userId){returnnewTuple<string,int>("Amogh",105);// Note that I can also use the existing helper method (Tuple.Create).}
Przeczytaj więcej o Tuple tutaj . Mam nadzieję że to pomoże.
Zakładam, że nie chcesz zwrócić anonimowego typu lub tablicy (lub zawartości dynamicznej)
ozzy432836
0
Zmienianie kształtów obiektów, gdy trzeba je przesłać przez kabel lub przejść do innej warstwy aplikacji, a wiele obiektów zostaje połączonych w jedną:
Przykład:
var customerDetails =newTuple<Customer,List<Address>>(mainCustomer,newList<Address>{mainCustomerAddress}).ToCustomerDetails();
Parametr out jest świetny, gdy istnieje tylko kilka wartości, które należy zwrócić, ale gdy zaczniesz napotykać 4, 5, 6 lub więcej wartości, które muszą zostać zwrócone, może stać się nieporęczny. Inną opcją zwracania wielu wartości jest utworzenie i zwrócenie klasy / struktury zdefiniowanej przez użytkownika lub użycie krotki w celu spakowania wszystkich wartości, które mają zostać zwrócone przez metodę.
Pierwsza opcja, wykorzystująca klasę / strukturę do zwracania wartości, jest prosta. Po prostu utwórz typ (w tym przykładzie jest to struktura) w następujący sposób:
Druga opcja, używając krotki, jest jeszcze bardziej eleganckim rozwiązaniem niż użycie obiektu zdefiniowanego przez użytkownika. Można utworzyć krotkę do przechowywania dowolnej liczby wartości różnych typów. Ponadto dane przechowywane w krotce są niezmienne; Po dodaniu danych do krotki za pomocą konstruktora lub statycznej metody Create nie można ich zmienić. Krotki mogą akceptować maksymalnie osiem oddzielnych wartości. Jeśli chcesz zwrócić więcej niż osiem wartości, będziesz musiał użyć specjalnej klasy krotki: Klasa krotki Tworząc krotkę z więcej niż ośmioma wartościami, nie można użyć statycznej metody Create - zamiast tego należy użyć konstruktora klasy. Oto jak można utworzyć krotkę składającą się z 10 wartości całkowitych:
var values =newTuple<int,int,int,int,int,int,int,Tuple<int,int,int>>(1,2,3,4,5,6,7,newTuple<int,int,int>(8,9,10));
Oczywiście możesz nadal dodawać więcej krotek na końcu każdej osadzonej krotki, tworząc krotkę o dowolnym rozmiarze.
Tylko do prototypowania - krotki są bez znaczenia. Wygodne w użyciu, ale to tylko skrót! W przypadku prototypów - dobrze. Pamiętaj tylko, aby później usunąć ten kod.
Łatwe do napisania, trudne do odczytania. Nie ma widocznej przewagi nad klasami, klasami wewnętrznymi, klasami anonimowymi itp.
Cóż, wypróbowałem 3 sposoby rozwiązania tego samego problemu w C # 7 i znalazłem przypadek użycia dla krotek.
Praca z dynamicznymi danymi w projektach internetowych może czasami być uciążliwa podczas mapowania itp.
Podoba mi się sposób, w jaki krotka automatycznie mapowała się na element1, element2, elementN, co wydaje mi się bardziej niezawodne niż używanie indeksów tablicowych, w których możesz zostać złapany na elemencie spoza indeksu lub używając typu anonimowego, w którym możesz błędnie napisać nazwę właściwości.
Wydaje się, że DTO zostało stworzone za darmo tylko przy użyciu krotki i mogę uzyskać dostęp do wszystkich właściwości za pomocą itemN, co bardziej przypomina statyczne pisanie bez konieczności tworzenia oddzielnego DTO w tym celu.
Odpowiedzi:
O to właśnie chodzi - wygodniej jest nie tworzyć niestandardowej klasy lub struktury przez cały czas. Jest to ulepszenie
Action
lubFunc
... możesz samemu tworzyć te typy, ale wygodnie jest, aby istniały w ramach.źródło
convenient not to make a custom class
. Czy masz na myśli tworzenie niestandardowej instancji klasy za pomocą=new..()
?Dzięki krotkom można łatwo zaimplementować słownik dwuwymiarowy (lub n-wymiarowy, jeśli o to chodzi). Na przykład możesz użyć takiego słownika, aby zaimplementować mapowanie wymiany walut:
źródło
W magazynie MSDN jest doskonały artykuł, który mówi o bólach brzucha i kwestiach projektowych, które doprowadziły do dodania Tuple do BCL. Szczególnie interesujący jest wybór między typem wartości a typem referencyjnym.
Jak wyjaśnia artykuł, siłą napędową Tuple było tak wiele grup wewnątrz firmy Microsoft, które miały z tego pożytek, zespół F # z przodu. Chociaż nie zostało to wspomniane, uważam, że nowe słowo kluczowe „dynamiczne” w C # (i VB.NET) również miało z tym coś wspólnego, krotki są bardzo powszechne w językach dynamicznych.
Poza tym tworzenie własnego poco nie jest szczególnie lepsze, przynajmniej możesz nadać członkom lepszą nazwę.
AKTUALIZACJA: w związku z dużą rewizją w C # wersji 7, teraz otrzymuję dużo więcej miłości do składni. Wstępne ogłoszenie w tym poście na blogu .
źródło
Oto mały przykład - załóżmy, że masz metodę, która musi wyszukać uchwyt użytkownika i adres e-mail, biorąc pod uwagę identyfikator użytkownika. Zawsze możesz utworzyć niestandardową klasę, która zawiera te dane, lub użyć parametru ref / out dla tych danych, lub możesz po prostu zwrócić krotkę i mieć ładną sygnaturę metody bez konieczności tworzenia nowego POCO.
źródło
Tuple<bool, T> TryParse<T>(string input)
i zamiast używać parametru wyjściowego, otrzymujesz obie wartości z powrotem w krotce.Użyłem krotki, aby rozwiązać problem 11 projektu Euler :
Teraz mogę rozwiązać cały problem za pomocą:
I mógłby być stosowany typ niestandardowy dla tego, ale byłoby to wyglądało dokładnie tak, jak krotki .
źródło
Składnia krotki w języku C # jest absurdalnie obszerna, więc deklarowanie krotek jest trudne. I nie ma dopasowywania wzorców, więc są również bolesne w użyciu.
Ale czasami potrzebujesz tylko grupowania obiektów ad hoc bez tworzenia dla niego klasy. Na przykład, powiedzmy, że chciałem zagregować listę, ale chciałem mieć dwie wartości zamiast jednej:
Zamiast łączyć zbiór wartości w jeden wynik, rozwińmy pojedynczy wynik do zbioru wartości. Najłatwiejszym sposobem zapisania tej funkcji jest:
f
konwertuje stan na krotkę. Zwracamy pierwszą wartość z krotki i ustawiamy nasz nowy stan na drugą wartość. To pozwala nam zachować stan podczas obliczeń.Używasz go jako takiego:
evens
jest dość prosty, alefibs
jest trochę sprytniejszy. Wstate
rzeczywistości jest to krotka, która zawiera odpowiednio fib (n-2) i fib (n-1).źródło
new Tuple<Guid,string,...>
Nie podoba mi się ich nadużywanie, ponieważ tworzą kod, który nie wyjaśnia samego siebie, ale są niesamowite w implementacji kluczy złożonych w locie, ponieważ implementują IStructuralEquatable i IStructuralComparable (do użycia zarówno do wyszukiwania, jak i porządkowania cele).
I łączą wewnętrznie hashcody wszystkich swoich elementów; na przykład tutaj jest GetHashCode Tuple (pobrane z ILSpy):
źródło
Krotki doskonale nadają się do wykonywania wielu asynchronicznych operacji we / wy na raz i zwracania wszystkich wartości razem. Oto przykłady robienia tego z Tuple i bez. Krotki mogą faktycznie uczynić twój kod bardziej przejrzystym!
Bez (paskudnego zagnieżdżenia!):
Dzięki Tuple
Jeśli korzystasz z funkcji anonimowego typu domniemanych zresztą wtedy nie robią kod mniej jasna za pomocą krotka. Ponowne dostrojenie krotki z metody? Moim skromnym zdaniem używaj oszczędnie, gdy klarowność kodu jest kluczowa. Wiem, że programowaniu funkcjonalnemu w C # trudno się oprzeć, ale musimy wziąć pod uwagę tych wszystkich starych, niezgrabnych programistów C # zorientowanych obiektowo.
źródło
Krotki są intensywnie używane w językach funkcjonalnych, które mogą robić z nimi więcej rzeczy, teraz F # jest „oficjalnym” językiem .net, z którym można współpracować z C # i przekazywać je między kodem napisanym w dwóch językach.
źródło
Zwykle unikam
Tuple
w większości scenariuszy, ponieważ szkodzi to czytelności. Jest to jednakTuple
przydatne, gdy trzeba pogrupować niepowiązane dane.Na przykład załóżmy, że masz listę samochodów i miast, w których zostały zakupione:
Chcesz zsumować liczby dla każdego samochodu na miasto:
Aby to zrobić, tworzysz plik
Dictionary
. Masz kilka opcji:Dictionary<string, Dictionary<string, int>>
.Dictionary<CarAndCity, int>
.Dictionary<Tuple<string, string>, int>
.Pierwsza opcja powoduje utratę czytelności. Będziesz musiał napisać dużo więcej kodu.
Druga opcja działa i jest zwięzła, ale samochód i miasto nie są tak naprawdę powiązane i prawdopodobnie nie należą do jednej klasy razem.
Trzecia opcja jest zwięzła i przejrzysta. To dobry użytek z
Tuple
.źródło
Kilka przykładów z mojej głowy:
Na przykład nie chciałbyś dołączać System.Drawing do aplikacji internetowej tylko po to, aby używać Point / PointF i Size / SizeF.
źródło
Tuple
jest równie przydatny w sytuacjach krytycznych, jakPoint
lubSomeVector
może być przydatny podczas wykonywania operacji graficznych. Podkreśla dwie wartości, które są ze sobą bardzo powiązane. Często widzę właściwości o nazwach StartTime i EndTime podczas czytania kodu, ale nawet lepiej niż data, godzina i czas trwania, krotka zmusza cię do rozważenia obu wartości za każdym razem, gdy działasz w tym obszarze logiki biznesowej. Lub zwracanie „hej, dane się zmieniły (bool), oto dane (inny typ)” w ciężkim przetwarzaniu zamiast przechodzenia przez intensywne powiązania.Powinieneś być bardzo ostrożny podczas używania
Tuple
i prawdopodobnie dwa razy pomyśleć, zanim to zrobisz. Z mojego wcześniejszego doświadczenia dowiedziałem się, że używanieTuple
bardzo utrudnia czytanie i obsługę kodu w przyszłości. Jakiś czas temu musiałem naprawić kod, w którym krotki były używane prawie wszędzie. Zamiast myśleć o odpowiednich modelach obiektowych, używali po prostu krotek. To był koszmar ... czasami chciałem zabić gościa, który napisał kod ...Nie chcę mówić, że nie powinieneś używać
Tuple
i to jest złe czy coś i jestem w stu procentach pewien, że są zadania, w którychTuple
jest najlepszym kandydatem do użycia, ale prawdopodobnie powinieneś się jeszcze raz zastanowić, czy NAPRAWDĘ tego potrzebujesz ?źródło
Najlepszym zastosowaniem dla krotek, które znalazłem, jest zwrócenie więcej niż jednego typu obiektu z metody, wiesz, jakie będą typy obiektów i liczba, i nie jest to długa lista.
Inną prostą alternatywą byłoby użycie parametru „out”
lub tworzenie słownika
Użycie krotki pozwala jednak uniknąć tworzenia obiektu „out” lub konieczności przeszukiwania hasła w słowniku;
źródło
Właśnie znalazłem rozwiązanie jednego z moich problemów w Tuple. Jest to podobne do deklarowania klasy w zakresie metody, ale z leniwym deklarowaniem nazw jej pól. Operujesz na kolekcjach krotek, ich pojedynczych wystąpieniach, a następnie na podstawie swojej krotki tworzysz kolekcję typu anonimowego z wymaganymi nazwami pól. Pozwala to uniknąć tworzenia nowej klasy w tym celu.
Zadaniem jest napisanie odpowiedzi JSON z LINQ bez żadnych dodatkowych klas:
Oczywiście moglibyśmy to zrobić deklarując nową klasę dla moich grup, ale pomysł stworzenia takich anonimowych kolekcji bez deklarowania nowych klas.
źródło
Cóż, w moim przypadku musiałem użyć krotki, gdy dowiedziałem się, że nie możemy użyć parametru out w metodzie asynchronicznej. Przeczytaj o tym tutaj . Potrzebowałem też innego typu zwrotu. Więc zamiast tego użyłem krotki jako mojego typu zwracanego i oznaczyłem metodę jako asynchroniczną.
Przykładowy kod poniżej.
Przeczytaj więcej o Tuple tutaj . Mam nadzieję że to pomoże.
źródło
Zmienianie kształtów obiektów, gdy trzeba je przesłać przez kabel lub przejść do innej warstwy aplikacji, a wiele obiektów zostaje połączonych w jedną:
Przykład:
Metoda rozszerzenia:
źródło
Parametr out jest świetny, gdy istnieje tylko kilka wartości, które należy zwrócić, ale gdy zaczniesz napotykać 4, 5, 6 lub więcej wartości, które muszą zostać zwrócone, może stać się nieporęczny. Inną opcją zwracania wielu wartości jest utworzenie i zwrócenie klasy / struktury zdefiniowanej przez użytkownika lub użycie krotki w celu spakowania wszystkich wartości, które mają zostać zwrócone przez metodę.
Pierwsza opcja, wykorzystująca klasę / strukturę do zwracania wartości, jest prosta. Po prostu utwórz typ (w tym przykładzie jest to struktura) w następujący sposób:
Druga opcja, używając krotki, jest jeszcze bardziej eleganckim rozwiązaniem niż użycie obiektu zdefiniowanego przez użytkownika. Można utworzyć krotkę do przechowywania dowolnej liczby wartości różnych typów. Ponadto dane przechowywane w krotce są niezmienne; Po dodaniu danych do krotki za pomocą konstruktora lub statycznej metody Create nie można ich zmienić. Krotki mogą akceptować maksymalnie osiem oddzielnych wartości. Jeśli chcesz zwrócić więcej niż osiem wartości, będziesz musiał użyć specjalnej klasy krotki: Klasa krotki Tworząc krotkę z więcej niż ośmioma wartościami, nie można użyć statycznej metody Create - zamiast tego należy użyć konstruktora klasy. Oto jak można utworzyć krotkę składającą się z 10 wartości całkowitych:
Oczywiście możesz nadal dodawać więcej krotek na końcu każdej osadzonej krotki, tworząc krotkę o dowolnym rozmiarze.
źródło
Tylko do prototypowania - krotki są bez znaczenia. Wygodne w użyciu, ale to tylko skrót! W przypadku prototypów - dobrze. Pamiętaj tylko, aby później usunąć ten kod.
Łatwe do napisania, trudne do odczytania. Nie ma widocznej przewagi nad klasami, klasami wewnętrznymi, klasami anonimowymi itp.
źródło
Cóż, wypróbowałem 3 sposoby rozwiązania tego samego problemu w C # 7 i znalazłem przypadek użycia dla krotek.
Praca z dynamicznymi danymi w projektach internetowych może czasami być uciążliwa podczas mapowania itp.
Podoba mi się sposób, w jaki krotka automatycznie mapowała się na element1, element2, elementN, co wydaje mi się bardziej niezawodne niż używanie indeksów tablicowych, w których możesz zostać złapany na elemencie spoza indeksu lub używając typu anonimowego, w którym możesz błędnie napisać nazwę właściwości.
Wydaje się, że DTO zostało stworzone za darmo tylko przy użyciu krotki i mogę uzyskać dostęp do wszystkich właściwości za pomocą itemN, co bardziej przypomina statyczne pisanie bez konieczności tworzenia oddzielnego DTO w tym celu.
źródło