2011-12-15 3 views
11

В Python я могу написатьПоддержка наборов и распаковки в 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 

Но в C# Я считаю себя выписывая

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 

Путь Pythonic является obivously гораздо чище. Есть ли способ сделать это на C#?

+1

Я бы, вероятно, использовал для этого параметры. –

+1

@MikeChristensen: Руководства по дизайну каркаса рекомендуют против параметров, если их можно избежать. – dtb

+1

@MikeChristensen Я думал о параметрах, но они почему-то заставляют меня чувствовать себя грязным –

ответ

14

Там целый набор Tuple классов в .NET:

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

Но нет компактного синтаксиса для распаковки их, как в Python:

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

Примечание для причинного читателя: 'Tuple <...>' является стандартным только в .NET4 +. –

+0

Примечание для других читателей 2-кортеж может быть создан в .NET <4 (по существу) с использованием KeyValuePair. – fabspro

1

C# является строго типизированным языком с типом система, которая обеспечивает правило, что функции могут иметь либо none (void), либо 1 возвращаемое значение. C# 4.0 вводит класс 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

Сильно типизированный язык не ограничивается возвратом одного значения. Схема является одним из примеров. Сильная типизация! = Статическая типизация; Python и Scheme сильно, но динамически типизированы. –

+2

Это верно, вероятно, должно быть указано, что система типов C# ограничивает возвращаемые значения функций одним типом. –

+0

Действительно, это правда :) –

6

Расширение может получить его ближе к Python кортежа распаковке, не более эффективным, но более удобным для чтения (и 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

Поскольку C# 7, вы можете использовать ValueTuple:

Install-Package System.ValueTuple 

Затем вы можете упаковать и распаковать ValueTuples:

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

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