2009-10-31 12 views
5

W Ruby można zrobić coś takiego:Czy możesz przekazać tablicę "rozszerzoną" do funkcji w C#, jak w Ruby?

def method(a, b) ... end 
myMethod(*myArray) 

Więc jeśli myArray miał 2 pozycji, byłoby to równoznaczne z tym:

myMehtod(myArray[0], myArray[1]) 

Tak, że w organizmie metodzie == myArray [0] ib == myArray [1]

Czy możesz to zrobić w C#? (Tak więc mogę mieć zadeklarowaną metodę z jawnymi argumentami, zamiast tylko przyjmować tablicę jako argument)

EDYCJA: Powinienem być bardziej szczegółowy o wywoływanej metodzie.

Odpowiedz

9

Twoja metoda może być uznana zaakceptować szereg parametrów, poprzez params:

void F(params int[] foo) { 
    // Do something with foo. 
} 

Teraz możesz albo przekazać arbitralne numer int s do metody lub tablicy int. Ale biorąc pod uwagę stałą deklarację metody, użytkownik nie może rozwinąć tablicy w locie, jak to tylko możliwe w Ruby, ponieważ parametry są obsługiwane inaczej pod maską (uważam, że jest inaczej w Ruby), a ponieważ C# nie jest równie dynamiczny.

Teoretycznie można użyć odbicia, aby wywołać metodę, aby osiągnąć ten sam efekt, chociaż (odzwierciedlone wywołania metod zawsze akceptują tablicę parametrów).

+0

mógłbym skończyć za pomocą odbitego rzeczą, aby to działało tak, jak chcesz, ale to jest ciekawe. Dzięki! –

6

Jeśli zadeklarujesz argumenty funkcji z parametrem params, możesz przekazać w postaci tablicy lub dowolną liczbę pojedynczych parametrów.

Na przykład:

public class Foo 
{ 
    public static void Main() 
    { 
     int[] x = new int[] {1,2,3}; 
     Bar(x); 
     Bar(10,11,12); 
    } 

    public static void Bar(params int[] quux) 
    { 
     foreach(int i in quux) 
     { 
      System.Console.WriteLine(i); 
     } 
    } 
} 

produkuje

1 
2 
3 
10 
11 
12 
0

Można to zrobić:

void MyMethod(params MyType[] args) 
{ 
} 


MyMethod(myObject1, myObject2, myObject3); 

MyType[] a = { new MyType(), new MyType() }; 
MyMethod(a); 
1

Nie, nie można mieć macierz "auto-rozwinąć" gdy przekazany jako argument do metody C#. Jednym ze sposobów symulujący tej metody jest pisanie przeciąża:

MyMethod(int a, int b) { /* ... */ } 

MyMethod(int[] c) 
{ 
    // check array length? 
    MyMethod(c[0], c[1]); 
} 

AnotherMethod() 
{ 
    int[] someArray = new[] {1,2}; 

    MyMethod(someArray); // valid 
    MyMethod(1,2);  // valid 
} 

Ale jak kilka inni już wspomniano, jest to prostsze (i trochę na odwrót), aby użyć słowa kluczowego params. W moim przykładzie (i twoim) zawsze kończy się posiadanie oddzielnych a i b. Z params zawsze masz do czynienia z tablicą.

0

Mam metodę PostServer(string path, params object[] objects), która umieszcza json na moim serwerze. Ale zanim wyślę moją tablicę obiektów, na jej początku ustawiam token sesji.

string access_token = "<access_token>"; 
string url = "http://example.com"; 

void PostJson(string path, params object[] objects) { 
    SendHttp(url + path, HttpMethod.POST, JSON.Stringify(objects)); 
} 

void PostServer(string path, params object[] objects) { 
    object[] moreObjects = new object[objects.Length + 1]; 
    object[0] = access_token; 
    objects.CopyTo(moreObjects, 1); 
    PostJson(path, moreObjects); // moreObjects will be expanded into PostJson objects 
} 

Potem ... PostServer("/greet", "Hello World!", true, 3.1415);

wyśle ​​json ["<access token>","Hello World!",true,3.1415] na moim serwerze.

Właściwie w praktyce umieszczam moreObjects w prawo w JSON.Stringify, ale masz rację.

Możesz więc rozbudowywać tablice, ale przekazałeś tablicę jako jedyny parametr params. W coffeescript można zrobić PostJson(path, access_token, objects...), ponieważ ma operatora splat ....

Jeśli próbowałeś PostJson(path, access_token, objects) wC# skończy się wysyłanie JSON ["<access_token>",["Hello World!",true,3.1415]]

Powiązane problemy