【问题标题】:Calling a method that takes a variable parameter list with an array调用带有数组的可变参数列表的方法
【发布时间】:2022-01-08 21:16:29
【问题描述】:

考虑这种方法:

public static void InvokeAsync(params object[] arguments)
{
    // do something
}

现在我想用string[] 类型的单个参数调用它:

InvokeAsync(new string[] { "Test" });

不幸的是,这导致arguments 成为string[] 实例和arguments[1] == "Test"。我需要将字符串数组作为 object[] 数组的第一个元素。

我可以通过以下方式解决这个问题:

InvokeAsync(new object[] { new string[] { "Test" }});

但这有点违背params 声明的目的,而且也不好(而且不明显!)。有没有更好的办法?

【问题讨论】:

  • “现在我想用一个字符串[]类型的参数来调用它”。那么你为什么首先使用params 声明呢?
  • 是否有特殊原因需要将其声明为采用 object[] 而不是特定类型的数组或使类通用?
  • @Powerlord 实际方法来自一个通过反射执行泛型调用的类。
  • @ShawnOrr 这就是问题所在。对于其他实际参数类型,一切都按预期工作。

标签: c# parameter-passing variadic-functions


【解决方案1】:

这是正确的方法。数组是covariant in C#,因此存在从string[]object[] 的隐式转换(这实际上不是类型安全的,请参阅链接的文档),编译器使用它来将您的new string[] { "Test" } 视为arguments 数组。因此,您需要通过此解决方法向编译器“解释”您真正想要的内容。

如果您实际上有多个参数,那么一切都会按预期工作:

InvokeAsync(new string[] { "Test" }, 1);

【讨论】:

    【解决方案2】:

    试试这个方法

    public static object InvokeAsync(params object[] arguments)
    {
      if (!arguments.GetType().Name.Contains("Object")) arguments = 
                                                         new object[] { arguments };
      return arguments;
    }
    
    

    测试

    var result1 =InvokeAsync(new string[] { "Test1","Test2"});
    var result2 =InvokeAsync(new string[] { "Test1","Test2"},new string[] { "Test3","Test4"} );
    var result3 =InvokeAsync(new string[] { "Test1","Test2"}, 3 );
    

    结果1

    [
      [
        "Test1",
        "Test2"
      ]
    ]
    

    结果2

    [
      [
        "Test1",
        "Test2"
      ],
      [
        "Test3",
        "Test4"
      ]
    ]
    

    结果 3

    [
      [
        "Test1",
        "Test2"
      ],
      1
    ]
    

    【讨论】:

      猜你喜欢
      • 2013-04-07
      • 1970-01-01
      • 1970-01-01
      • 2018-04-29
      • 2013-07-17
      • 2013-05-13
      • 1970-01-01
      • 1970-01-01
      • 2017-09-02
      相关资源
      最近更新 更多