开发者

Can you pass an 'expanded' array to a function in C# like in ruby?

开发者 https://www.devze.com 2022-12-10 09:21 出处:网络
In ruby you can do something like this: 开发者_运维百科def method(a, b) ... end myMethod(*myArray)

In ruby you can do something like this:

开发者_运维百科def method(a, b) ... end
myMethod(*myArray)

So if myArray had 2 items, it would be the equivalent of this:

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

So that in the method body, a == myArray[0] and b == myArray[1]

Can you do this in C#? (So I can have a method declared with explicit arguments, instead of just taking an array as the argument)

EDIT: I should've been more specific about the method being called.


Your method can be declared to accept a parameter array, via params:

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

Now you can either pass a arbitrary number of ints to the method, or an array of int. But given a fixed method declaration, you cannot expand an array on-the-fly as you can in Ruby, because the parameters are handled differently under the hood (I believe this is different in Ruby), and because C# isn’t quite as dynamic.

Theoretically, you can use reflection to call the method to achieve the same effect, though (reflected method calls always accept a parameter array).


If you declare your function's arguments with the params keyword, you can pass in an array or an arbitrary number of individual parameters.

For instance:

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

produces

1
2
3
10
11
12


No, you can't have the array "auto-expand" when passed as an argument to a C# method. One way of simulating this is writing method overloads:

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
}

But as a few others have already mentioned, it is simpler (and somewhat the reverse) to use the params keyword. In my example (and yours), you always end up having separate a and b. With params you always have an array to deal with.


You could do this:

void MyMethod(params MyType[] args)
{
}


MyMethod(myObject1, myObject2, myObject3);

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


I have a PostServer(string path, params object[] objects) method that posts json to my server. But before I send my objects array I prepend a session token to the front of it.

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
}

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

Will send the json ["<access token>","Hello World!",true,3.1415] on to my server.

Actually in practice I put moreObjects right into JSON.Stringify but you get the point.

So you can expand arrays, but you have pass an array as the only params parameter. In coffeescript you could do PostJson(path, access_token, objects...), because it has an splat operator ....

If you tried PostJson(path, access_token, objects) in c# you will end up sending the json ["<access_token>",["Hello World!",true,3.1415]]

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号