2011-12-15 20 views
11

En Python Puedo escribirTuplas y compatibilidad de asignación de desempaquetado 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 

Pero en C# me encuentro escribiendo

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 forma Pythonic es obivously mucho más limpio. ¿Hay alguna manera de hacer esto en C#?

+1

Probablemente usaría los parámetros para eso ... –

+1

@MikeChristensen: las Pautas de diseño de frameworks recomiendan en contra de los parámetros si pueden evitarse. – dtb

+1

@MikeChristensen Pensé en los parámetros, pero me hacen sentir sucio por alguna razón –

Respuesta

14

Hay un conjunto de Tuple clases en .NET:

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

Pero no hay sintaxis compacta para descomprimir ellos como en Python:

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

Nota para el lector causal: 'Tuple <...>' es estándar solo en .NET4 +. –

+0

Nota para otros lectores, una 2-tupla se puede crear en .NET <4 (en esencia) utilizando en su lugar un KeyValuePair. – fabspro

1

C# es un lenguaje fuertemente tipado con un tipo de sistema que impone una regla que las funciones pueden tener ninguno (void) o 1 valor de retorno. C# 4.0 introduce la clase de tupla:

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

Un lenguaje fuertemente tipado no está restringido a devolver un solo valor. Scheme es un ejemplo. Strong typing! = Tipeo estático; Python y Scheme tienen una tipificación fuerte pero dinámica. –

+2

Esto es cierto, probablemente debería estar redactado que el sistema de tipo C# restringe los valores de retorno de las funciones a un solo tipo. –

+0

De hecho, eso es cierto :) –

6

Una extensión puede conseguirlo más cerca de Python desembalaje tupla, no más eficiente, pero más fácil de leer (y 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

Puesto que C# 7, puede utilizar ValueTuple:

Install-Package System.ValueTuple 

A continuación, puede hacer y deshacer ValueTuples:

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

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