Можете ли вы передать «расширенный» массив функции в C #, как в ruby? - PullRequest
5 голосов
/ 01 ноября 2009

В ruby ​​вы можете сделать что-то вроде этого:

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

Так что если бы у myArray было 2 элемента, это было бы эквивалентно этому:

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

Чтобы в теле метода a == myArray [0] и b == myArray [1]

Можете ли вы сделать это в C #? (Таким образом, я могу иметь метод, объявленный с явными аргументами, вместо того, чтобы просто принимать массив в качестве аргумента)

РЕДАКТИРОВАТЬ: Я должен был быть более конкретным о вызываемом методе.

Ответы [ 5 ]

10 голосов
/ 01 ноября 2009

Ваш метод может быть объявлен для принятия массива параметров через params:

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

Теперь вы можете передать в метод произвольное число int s или массив int. Но, учитывая фиксированное объявление метода, вы не можете расширять массив «на лету», как в Ruby, потому что параметры обрабатываются по-разному (я считаю, что в Ruby это не так), и потому что C # не так динамичен.

Теоретически вы можете использовать отражение, чтобы вызвать метод для достижения того же эффекта, хотя (вызовы отраженного метода всегда принимают массив параметров).

7 голосов
/ 01 ноября 2009

Если вы объявите аргументы своей функции с помощью ключевого слова params , вы можете передать в массив или произвольное количество отдельных параметров.

Например:

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);
        }
    }
}

1010 * производит *

1
2
3
10
11
12
1 голос
/ 01 ноября 2009

Нет, у вас не может быть массива "авторазвертывание" при передаче в качестве аргумента методу C #. Один из способов смоделировать это - перегрузка метода записи:

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
}

Но, как уже упоминали некоторые другие, проще (и несколько наоборот) использовать ключевое слово params. В моем (и вашем) примере у вас всегда есть отдельные a и b. С params у вас всегда есть массив для работы.

0 голосов
/ 14 февраля 2017

У меня есть метод PostServer(string path, params object[] objects), который отправляет JSON на мой сервер. Но прежде чем отправить массив объектов, я добавляю маркер сеанса к его началу.

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
}

Тогда ... PostServer("/greet", "Hello World!", true, 3.1415);

Отправит JSON ["<access token>","Hello World!",true,3.1415] на мой сервер.

На самом деле на практике я помещаю moreObjects прямо в JSON.Stringify, но вы понимаете, в чем дело.

Таким образом, вы можете расширять массивы, но вы должны передать массив в качестве единственного параметра params. В coffeescript вы можете сделать PostJson(path, access_token, objects...), потому что у него есть оператор сплата ....

Если вы попытались PostJson(path, access_token, objects) в C #, вы в конечном итоге отправите JSON ["<access_token>",["Hello World!",true,3.1415]]

0 голосов
/ 01 ноября 2009

Вы можете сделать это:

void MyMethod(params MyType[] args)
{
}


MyMethod(myObject1, myObject2, myObject3);

MyType[] a = { new MyType(),  new MyType() };
MyMethod(a);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...