Czy istnieje sposób na użycie klasy Tuple, ale podać w niej nazwy przedmiotów?
Na przykład:
public Tuple<int, int, int int> GetOrderRelatedIds()
Zwraca identyfikatory OrderGroupId, OrderTypeId, OrderSubTypeId i OrderRequirementId.
Byłoby miło poinformować użytkowników mojej metody, która jest która. (Po wywołaniu metody wyniki są następujące: item1, result.Item2, result.Item3, result.Item4. Nie jest jasne, który jest który.)
(Wiem, że mógłbym po prostu stworzyć klasę do przechowywania wszystkich tych identyfikatorów, ale jeśli identyfikatory te mają już własne klasy, w których żyją, a tworzenie klasy dla wartości zwracanej dla tej metody wydaje się głupie.)
Tuple
jest bardzo ogólny, więc to wszystko, co dostajeszOdpowiedzi:
W C # 7.0 (Visual Studio 2017) wprowadzono nową konstrukcję:
źródło
List<(int first, int second)>
. Musiałem pobrać pakiet System.ValueTuple z NuGet, aby uruchomić go w Visual Studio 2017.return (first: first, middle: middle, last: last);
return (first, middle, last);
w .NET 4.7.1 (ValueTuple
, chociaż zwykle świetne, jest zmiennym typem wartości (struct), podczas gdyTuple
jest niezmiennym typem odniesienia (klasa). O ile mi wiadomo, nie ma sposobu na uzyskanie typu referencyjnegoTuple
z przyjaznymi nazwami przedmiotów.Aż do wersji C # 7.0 nie było możliwości zrobienia tego bez zdefiniowania własnego typu.
źródło
Oto zbyt skomplikowana wersja tego, o co pytasz:
Dlaczego nie zrobić klasy?
źródło
Tuple<T, T2>
sobie, nie możesz być strukturą.Z .net 4 możesz być może spojrzeć na
ExpandoObject
, jednak nie używaj go w tym prostym przypadku, ponieważ to, co byłoby błędami kompilacji, stało się błędem czasu wykonywania.Coś innego, o czym warto wspomnieć, to anonimowy typ metody , ale musisz utworzyć klasę, jeśli chcesz ją zwrócić.
źródło
Odtworzenie mojej odpowiedzi z tego postu, ponieważ lepiej tutaj pasuje.
Począwszy C # 7.0, teraz jest to możliwe, aby wymienić właściwości krotki, które wcześniej używane do ustawień predefiniowanych nazwach takich jak
Item1
,Item2
i tak dalej.Nazewnictwo właściwości literałów Tuple :
Dane wyjściowe na konsoli:
Zwracanie krotki (o nazwanych właściwościach) z metody :
Dane wyjściowe na konsoli:
Tworzenie listy krotek o nazwanych właściwościach
Dane wyjściowe na konsoli:
Mam nadzieję, że wszystko omówiłem. Jeśli coś mi umknęło, proszę o komentarz w komentarzach.
Uwaga : Moje fragmenty kodu używają funkcji interpolacji ciągów w C # v7, jak wyszczególniono tutaj .
źródło
MichaelMocko Ansided jest świetny,
ale chcę dodać kilka rzeczy, które musiałem wymyślić
powyżej linii da ci błąd czasu kompilacji, jeśli używasz .NET Framework <4.7
Więc jeśli masz projekt, który używa frameworka .net <4.7 i nadal chcesz używać ValueTuple niż workAround, instalowałby ten pakiet nuget
źródło
Nie, nie możesz wymienić członków krotki.
Pośrednim rozwiązaniem byłoby użycie ExpandoObject zamiast Tuple.
źródło
Jeśli rodzaje twoich przedmiotów są różne, oto klasa, którą stworzyłem, aby uzyskać je bardziej intuicyjnie.
Zastosowanie tej klasy:
Kod źródłowy:
źródło
Jest to bardzo denerwujące i spodziewam się, że przyszłe wersje C # zaspokoją tę potrzebę. Uważam, że najłatwiejszym rozwiązaniem jest albo użycie innego typu struktury danych, albo zmiana nazwy „elementów” dla twojego zdrowia psychicznego i dla zdrowia innych osób czytających Twój kod.
źródło
Myślę, że stworzyłbym klasę, ale inną alternatywą są parametry wyjściowe.
Ponieważ twoja krotka zawiera tylko liczby całkowite, możesz ją przedstawić za pomocą
Dictionary<string,int>
ale ja też tego nie polecam.
źródło
Dlaczego wszyscy utrudniają życie. Krotki służą raczej do tymczasowego przetwarzania danych . Ciągła praca z Tuplesem w pewnym momencie bardzo utrudni zrozumienie kodu. Tworzenie klas dla wszystkiego może ostatecznie nadmuchać twój projekt.
Chodzi jednak o równowagę ...
Twój problem wydaje się być czymś, do czego chcesz klasę. I tylko ze względu na kompletność, ta klasa poniżej zawiera również konstruktory.
To jest właściwy wzorzec dla
Lub, jeśli chcesz to naprawdę proste: Możesz również użyć inicjatorów typu:
źródło
Chciałbym napisać nazwy przedmiotów w podsumowaniu .. więc po najechaniu myszką na funkcję helloworld () tekst powie: hello = Item1 i world = Item2
źródło
Wystarczy dodać do odpowiedzi @MichaelMocko. W tej chwili Tuple ma kilka gotch:
Nie można ich używać w drzewach wyrażeń EF
Przykład:
Nie uda się skompilować z błędem „Drzewo wyrażeń może nie zawierać literału krotkowego”. Niestety interfejs API drzew wyrażeń nie został rozszerzony o obsługę krotek, gdy zostały one dodane do języka.
Śledź ten problem i aktualizuj go: https://github.com/dotnet/roslyn/issues/12897
Aby obejść ten problem, możesz najpierw rzucić go na typ anonimowy, a następnie przekonwertować wartość na krotkę:
Inną opcją jest użycie ValueTuple.Create:
Bibliografia:
https://www.damirscorner.com/blog/posts/20181207-NoSupportForTuplesInExpressionTrees.html
Konwertuj typ anonimowy na nowy typ krotki C # 7
Nie można ich zdekonstruować w lambdach
Istnieje propozycja dodania obsługi: https://github.com/dotnet/csharplang/issues/258
Przykład:
Bibliografia:
Nie będą ładnie serializować
Nazwy pól krotek są dostępne tylko w czasie kompilacji i są całkowicie usuwane w czasie wykonywania.
Bibliografia:
źródło
Możesz napisać klasę zawierającą krotkę.
Musisz zastąpić funkcje Equals i GetHashCode
oraz operatory == i! =.
wróci:
Prawdziwe
Prawdziwe
źródło
Przykład krotki C # 7
źródło