2010-06-22 10 views
92

Sto guardando la nuova funzionalità C# di tuple. Sono curioso, quale problema era la tupla progettata per risolvere?Quale requisito era la tupla progettata per risolvere?

In che modo hai utilizzato le tuple nelle tue app?

Aggiornamento

Grazie per le risposte finora, fammi vedere se ho le cose a posto nella mia mente. Un buon esempio di tupla è stato indicato come coordinate. Questo sembra giusto?

var coords = Tuple.Create(geoLat,geoLong); 

quindi utilizzare il tuple in questo modo:

var myLatlng = new google.maps.LatLng("+ coords.Item1 + ", "+ coords.Item2 + "); 

E 'corretto?

+3

possibile duplicato di [? sta usando tuple nel mio .NET 4.0 Codice decisione cattiva progettazione] (http://stackoverflow.com/questions/3017352/is-using-tuples-in-my-net-4-0-code-a-poor-design-decision) –

+4

Bene, posso pensare a due risposte ... –

+13

Se il concetto di "coordinate" rende senso come classe, quindi lo farei diventare un corso. Usa le tuple per quelle situazioni in cui non esiste * un ragionevole concetto di "business logic" per l'insieme di dati che giustifica la creazione di un tipo. –

risposta

117

Durante la scrittura di programmi è estremamente comune voler raggruppare logicamente un insieme di valori che non hanno un'omogeneità sufficiente a giustificare la creazione di una classe.

Molti linguaggi di programmazione consentono di logico raggruppare un insieme di valori altrimenti non collegati senza creare un tipo in un solo modo:

void M(int foo, string bar, double blah) 

Logicamente questa è esattamente la stessa di un metodo di M che prende un argomento che è una 3-tupla di int, string, double. Ma spero che in realtà non lo faresti:

class MArguments 
{ 
    public int Foo { get; private set; } 
    ... etc 

a meno che i Titoli non avessero un altro significato nella logica di business.

Il concetto di "raggruppare un gruppo di dati altrimenti non correlati in una struttura più leggera di una classe" è utile in molti, molti posti, non solo per gli elenchi di parametri dei parametri formali. È utile quando un metodo ha due elementi da restituire o quando si desidera digitare un dizionario su due dati anziché su uno e così via.

Lingue come F # che supportano tipi di tupla in modo nativo offrono una grande flessibilità ai loro utenti; sono un insieme estremamente utile di tipi di dati. Il team BCL ha deciso di collaborare con il team di F # per standardizzare un tipo di tupla per il framework in modo che ogni lingua potesse trarne vantaggio.

Tuttavia, a questo punto non esiste il supporto lingua per le tuple in C#. Le tuple sono solo un altro tipo di dati come qualsiasi altra classe di framework; non c'è niente di speciale in loro. Stiamo considerando l'aggiunta di un migliore supporto per le tuple nelle ipotetiche future versioni di C#. Se qualcuno ha qualche idea su che tipo di funzionalità coinvolgono le tuple che vorresti vedere, sarei felice di trasmetterle al team di progettazione. Gli scenari realistici sono più convincenti delle riflessioni teoriche.

+0

Informazioni eccellenti. Non riesco ancora a pensare a un buon scenario per utilizzare le tuple nelle mie app, ma ora capisco meglio il concetto. Grazie! – Chaddeus

+0

Molto interessante vedere l'inizio della convergenza della lingua tra C# e F #. Forse cose come 'Asynch.Parallel' si presentano in ipotetiche versioni future di C#? – MalcomTucker

+1

@MalcomTucker: Asychrony e parallelismo sono decisamente nelle nostre menti come aree ricche in cui strumenti linguistici potrebbero essere utilizzati per risolvere problemi reali. Non penso che i flussi di lavoro asincroni in stile F # siano necessariamente la soluzione migliore per C#, ma sicuramente sono stimolanti. –

9

È spesso utile avere un tipo "coppia", utilizzato solo in situazioni rapide (come restituire due valori da un metodo). Le tuple sono una parte centrale dei linguaggi funzionali come F # e C# le ha raccolte lungo la strada.

+0

Grazie, ho aggiornato la domanda con più specifiche ... – Chaddeus

+0

System.Web.UI ha una coppia di classi http://msdn.microsoft.com/en-us/library/system.web.ui.pair.aspx. – StingyJack

5

molto utile per la restituzione di due valori da una funzione

+1

piuttosto come una struttura allora? – KevinDTimm

+1

Forse per il wrapping di un tipo anonimo? – bloparod

+1

I tipo li vedo come strutture anonime –

0

trovo il rinfrescante KeyValuePair in C# per scorrere i coppie di valori chiave in un dizionario.

+0

'KeyValuePair' può essere visualizzato come soluzione alternativa. In Python, l'iterazione su un 'dict' restituisce tuple (chiave, valore). – dan04

+0

Sì, come Python. :-) Non sapevo che KeyValuePair in C# non era una tupla? – Jubal

1

Una tupla viene spesso utilizzata per restituire più valori dalle funzioni quando non si desidera creare un tipo specifico. Se hai familiarità con Python, Python lo ha avuto per molto tempo.

1

Un uso comune potrebbe essere quello di evitare la creazione di classi/strutture che contiene solo 2 campi, invece si crea una Tupla (o una KeyValuePair per ora). utile come un valore di ritorno, evitare di passare N fuori params ...

12

Esso fornisce un'alternativa alla ref o out se si dispone di un metodo che ha bisogno di restituire più nuovi oggetti come parte della sua risposta.

Consente inoltre di utilizzare un tipo predefinito come tipo restituito se tutto ciò che occorre fare è creare due o tre tipi di mash-up esistenti e non si desidera aggiungere solo una classe/struct per questa combinazione. (Se si desidera una funzione può restituire un tipo anonimo? Questa è una risposta parziale a tale situazione.)

+0

Grazie, questa è una buona spiegazione. – Chaddeus

+0

Accidenti. Bello. Vorrei aver controllato cosa-tuple-sono pochi anni fa;). – sabiland

1

Restituzione di più di un valore da una funzione. getCoordinates() non è molto utile se restituisce solo x o y o z, ma anche la creazione di una classe completa e di un oggetto con tre interi sembra abbastanza pesante.

22

tuple fornire un'implementazione immutabile di una raccolta

parte gli usi comuni di tuple:

  • di valori comuni raggruppare senza dover creare una classe
  • restituire più valori da una funzione/metodo
  • ecc ...

Oggetti immutabili sono sicuri filo intrinsecamente:

oggetti immutabili possono essere utili in applicazioni multi-thread. Più thread possono agire su dati rappresentati da oggetti immutabili senza preoccuparsi dei dati modificati da altri thread. Pertanto, gli oggetti immutabili sono considerati più sicuri dei thread rispetto agli oggetti mutabili.

Da "Immutable Object" su wikipedia

+0

Grazie per aver aggiunto ulteriori informazioni alla domanda. Molto apprezzato. – Chaddeus

+0

Se si desidera una raccolta immutabile, è necessario utilizzare una raccolta immutabile, non una tupla. La differenza è che per la maggior parte delle collezioni non modificabili non è necessario specificare il numero di elementi in fase di compilazione –

+0

@ BlueRaja-DannyPflughoeft Indietro quando ho scritto questa risposta le classi di raccolta immutabili C# non erano ancora disponibili nel BCL. Immagino che cambierò 'raccolta' in 'oggetto' da quando MS ha sterilizzato l'implementazione Tuple in C# –

0

sono incappato in questo benchmark performanve tra tuple e le coppie chiave-valore e probabilmente tou lo troverà interessante. In sintesi dice che Tuple ha un vantaggio perché è un calss, quindi è archiviato nell'heap e non nello stack e quando viene passato in giro come argomento il suo puntatore è l'unica cosa che sta andando. Ma KeyValuePair è una struttura quindi è più veloce da allocare, ma è più lento quando viene utilizzato.

http://www.dotnetperls.com/tuple-keyvaluepair

0

sua davvero utile mentre tornava valori dalle funzioni. Possiamo avere più valori e questo è piuttosto un risparmio in alcuni scenari.

4

Personalmente, ritengo che Tuples sia una parte iterativa dello sviluppo quando sei in un ciclo investigativo, o semplicemente "giocando". Dato che una Tuple è generica, tendo a pensarci quando lavoro con parametri generici - specialmente quando voglio sviluppare un pezzo generico di codice, e sto iniziando dal codice, invece di chiedermi "come mi piacerebbe questa chiamata? guardare?".

Molto spesso mi rendo conto che la raccolta che le forme Tuple diventano parte di una lista, e fissando List> non esprime veramente l'intenzione della lista, o come funziona. Io spesso "vivo" con esso, ma mi trovo a voler manipolare la lista e cambiare un valore - a quel punto, non voglio necessariamente creare una nuova tupla per questo, quindi ho bisogno di creare la mia classe o struttura per tenerlo, così posso aggiungere codice di manipolazione.

Ovviamente esistono sempre metodi di estensione, ma molto spesso non si desidera estendere tale codice aggiuntivo alle implementazioni generiche.

Ci sono state volte in cui desidero esprimere i dati come Tupla e non sono disponibili Tuple. (VS2008) nel qual caso ho appena creato la mia classe Tuple - e non la rendono thread-safe (immutabile).

Quindi immagino che io sia dell'opinione che Tuples sia una programmazione pigra a spese di perdere un nome di tipo che descrive il suo scopo. L'altra spesa è che devi dichiarare la firma della Tupla ovunque sia usata come parametro. Dopo un certo numero di metodi che iniziano a sembrare gonfiati, potresti sentirti come me, che vale la pena fare una lezione, poiché pulisce le firme dei metodi.

Tendo ad avere la classe come membro pubblico della classe in cui stai già lavorando. Ma nel momento in cui si estende oltre una semplice serie di valori, ottiene il proprio file e io lo sposto da la classe contenente

Quindi, a posteriori, credo di usare Tuples quando non voglio andare a scrivere una lezione, e voglio solo pensare a quello che ho scritto in questo momento. Il che significa che la firma della Tuple potrebbe cambiare parecchio nel testo di mezz'ora, mentre capisco di quali dati ho bisogno per questo metodo e come restituisce i valori che restituirà.

Se ho la possibilità di fare il codice refactoring, spesso mi interrogo su un posto di Tuple.

1

Vecchia domanda dal 2010 e ora nel 2017 Dotnet cambia e diventa più intelligente.

C# 7 introduce il supporto del linguaggio per tuple, che abilita i nomi semantici per i campi di una tupla usando nuovi tipi di tuple più efficienti.

in VS 2017 e .Net 4.7 (o l'installazione di NuGet pacchetto System.ValueTuple), è possibile creare/utilizzare una tupla in un modo molto efficiente e semplice:

 var person = (Id:"123", Name:"john"); //create tuble with two items 
    Console.WriteLine($"{person.Id} name:{person.Name}") //access its fields 

Tornando più di un valore da un metodo:

public (double sum, double average) ComputeSumAndAverage(List<double> list) 
    { 
     var sum= list.Sum(); 
     var average = sum/list.Count; 
     return (sum, average); 
    } 

    How to use: 

     var list=new List<double>{1,2,3}; 
     var result = ComputeSumAndAverage(list); 
     Console.WriteLine($"Sum={result.sum} Average={result.average}");  

Per maggiori dettagli leggere: https://docs.microsoft.com/en-us/dotnet/csharp/tuples

Problemi correlati