你能像 ruby 一样将“扩展”数组传递给 C# 中的函数吗?

问题描述 投票:0回答:6

在 ruby 中你可以做这样的事情:

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

因此,如果 myArray 有 2 个项目,则相当于:

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

因此在方法体中,a == myArray[0] 且 b == myArray[1]

你能用 C# 做到这一点吗? (所以我可以使用显式参数声明一个方法,而不是仅仅将数组作为参数)

编辑:我应该更具体地说明被调用的方法。

c# methods
6个回答
16
投票

您的方法可以声明为接受参数数组,通过

params
:

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

现在您可以将任意数量的

int
传递给该方法,或者传递一个
int
数组。但是给定一个固定的方法声明,你不能像在 Ruby 中那样动态扩展数组,因为参数在幕后的处理方式不同(我相信这在 Ruby 中是不同的),而且因为 C# 不是相当动态。

理论上,您可以使用反射来调用方法来达到相同的效果(反射方法调用总是接受参数数组)。


12
投票

如果您使用 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);
        }
    }
}

产生

1
2
3
10
11
12

1
投票

不,当将数组作为参数传递给 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
投票

你可以这样做:

void MyMethod(params MyType[] args)
{
}


MyMethod(myObject1, myObject2, myObject3);

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

0
投票

我有一个

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...)
,因为它有一个splat操作符
...

如果您在 c# 中尝试过

PostJson(path, access_token, objects)
,您最终将发送 json
["<access_token>",["Hello World!",true,3.1415]]


0
投票

这在 C# 12 中“在某种程度上”是可能的。他们称之为“扩展运算符”;其他一些语言使用术语“splat”。

您只需在数组前面添加两个句点,这会将该数组扩展为其各个元素:

int[] row0 = [1, 2, 3];
int[] row1 = [4, 5, 6];
int[] row2 = [7, 8, 9];
int[] single = [.. row0, .. row1, .. row2];

foreach (var element in single)
{
    Console.Write($"{element}, ");
}
// output:
// 1, 2, 3, 4, 5, 6, 7, 8, 9,

不幸的是,它只能在内部新的“集合表达式”结构中工作。

更多信息:https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-12#collection-expressions

© www.soinside.com 2019 - 2024. All rights reserved.