2011-12-15 1 views
11

En Python Je peux écrirePrise en charge des affectations de tuples et de déballage en C#?

def myMethod(): 
    #some work to find the row and col 
    return (row, col) 

row, col = myMethod() 
mylist[row][col] # do work on this element 

Mais en C# Je me retrouve à écrire sur

int[] MyMethod() 
{ 
    // some work to find row and col 
    return new int[] { row, col } 
} 

int[] coords = MyMethod(); 
mylist[coords[0]][coords[1]] //do work on this element 

La façon dont Pythonic est obivously beaucoup plus propre. Y a-t-il un moyen de le faire en C#?

+1

J'utiliserais probablement des paramètres pour cela .. –

+1

@MikeChristensen: Les directives de conception de cadre recommandent d'éviter les paramètres s'ils peuvent être évités. – dtb

+1

@MikeChristensen J'ai pensé à des paramètres, mais ils me font sentir sale pour une raison quelconque –

Répondre

14

Il y a un ensemble de Tuple classes .NET:

Tuple<int, int> MyMethod() 
{ 
    // some work to find row and col 
    return Tuple.Create(row, col); 
} 

Mais il n'y a pas de syntaxe compacte pour les déballer comme en Python:

Tuple<int, int> coords = MyMethod(); 
mylist[coords.Item1][coords.Item2] //do work on this element 
+2

Note pour le lecteur causal: «Tuple <...>» est standard dans .NET4 + seulement. –

+0

Note pour les autres lecteurs, un 2-tuple peut être créé en .NET <4 (en substance) en utilisant un KeyValuePair à la place. – fabspro

1

C# est un langage fortement typé avec un type système qui applique une règle dont les fonctions peuvent avoir aucune (void) ou 1 valeur de retour. C# 4.0 introduit la classe Tuple:

Tuple<int, int> MyMethod() 
{ 
    return Tuple.Create(0, 1); 
} 

// Usage: 
var myTuple = MyMethod(); 
var row = myTuple.Item1; // value of 0 
var col = myTuple.Item2; // value of 1 
+13

Une langue fortement typée n'est pas limitée au renvoi d'une seule valeur. Le schéma est un exemple. Forte dactylographie! = Typage statique; Python et Scheme sont fortement mais dynamiquement typés. –

+2

Ceci est vrai, il devrait probablement être formulé que le système de type C# restreint les valeurs de retour des fonctions à un seul type. –

+0

En effet, c'est vrai :) –

6

Une extension peut obtenir plus de déballer tuple Python, pas plus efficace mais plus lisible (et Pythonic):

public class Extensions 
{ 
    public static void UnpackTo<T1, T2>(this Tuple<T1, T2> t, out T1 v1, out T2 v2) 
    { 
    v1 = t.Item1; 
    v2 = t.Item2; 
    } 
} 

Tuple<int, int> MyMethod() 
{ 
    // some work to find row and col 
    return Tuple.Create(row, col); 
} 

int row, col;  
MyMethod().UnpackTo(out row, out col); 
mylist[row][col]; // do work on this element 
8

Depuis C# 7, vous pouvez utiliser ValueTuple:

Install-Package System.ValueTuple 

Ensuite, vous pouvez emballer et déballer ValueTuples:

(int, int) MyMethod() 
{ 
    return (row, col); 
} 

(int row, int col) = MyMethod(); 
// mylist[row][col]