【问题标题】:Generic method arguments通用方法参数
【发布时间】:2020-03-26 11:27:26
【问题描述】:

我有一个接受 string[] 参数的方法

public static void MyMethod(string[] s1, string[] s2, string[] s3, string[] s4)
{

}

有时我的情况是,我想使用普通的string 而不是string[]

是否可以将方法的通用参数设置为接受数组或纯文本?

我需要什么(例子):

MyMethod(["a", "b"], ["s", "m"], ["i", "k"], ["a", "e"])
MyMethod(["a", "p"], "u", ["v", "p"], "e")
MyMethod("a", "b", "b", "d")

和其他组合

【问题讨论】:

  • 尝试类似:public static void MyMethod(params string[] s) 和重载public static void MyMethod(params string s)
  • 这不是泛型所做的string 不是string[],通用参数即使是也无济于事。正如其他人所说,这就是函数重载的目的。或者,您的调用者可以简单地将单个字符串放入数组中 来调用此方法。
  • 你可以为输入参数创建一个自己的类——比如StringInput类,它可以隐藏包含一个字符串或一个数组的细节。它可以有多个具有不同类型的构造函数,因此可以从数组和单个字符串创建它,并且它可以具有像IsSingleString()GetStringsAsArray() 这样的方法来帮助您以通用方式实现逻辑。
  • @DontVoteMeDown params 应该是一维数组。恐怕您的第二次重载甚至无法编译!
  • @Annosz 是的,我也建议这样做,加上从 string 和 string[] 到该类型的隐式转换运算符,然后使用参数使函数接受该类型。

标签: c# .net methods


【解决方案1】:

您可以使用params 关键字:

public static void MyMethod(params string[] s)
{

}

通过这种方式,您可以将一个简单的字符串作为参数传递给您的方法,如下所示:

MyMethod("str");

或多个值作为数组:

MyMethod("str1","str2","str3");

根据您在更新问题中的期望结果,您可能会发现以下实现也很有用:

public static void MyMethod(params string[][] s)
{

}

这适用于您在问题的我需要什么部分中提到的所有示例。

【讨论】:

    【解决方案2】:

    有趣。正如其他人所说,您需要的是使用 params 和支持来自 stringstring[] 的隐式转换的间接/自定义类型。

    例如:

    public static void MyMethod(params StringArray[] s)
    {   
    }
    
    class StringArray
    {
        public string[] Value { get; set; }
    
        public static implicit operator StringArray(string str)
        {
            return new StringArray
            {
                Value = new[] { str }
            };
        }
    
        public static implicit operator StringArray(string[] str)
        {
            return new StringArray
            {
                Value = str
            };
        }
    }
    

    那么你可以这样做:

    MyMethod(new[] { "a", "b" }, new[] { "s", "m" }, new[] { "i", "k" }, new[] { "a", "e" });
    MyMethod(new[] { "a", "p" }, "u", new[] { "v", "p" }, "e");
    MyMethod("a", "b", "b", "d");
    

    【讨论】:

      【解决方案3】:

      包装类型和隐式运算符是可能的。或者,您可以添加属性 IsCollection 来检查包装器是如何初始化的。

      class Program
      {
          static void MyMethod(StringCollection s1, StringCollection s2, StringCollection s3, StringCollection s4)
          {
      
          }
      
          static void Main(string[] args)
          {
              MyMethod("a", "b", "c", "d");
              MyMethod(new[] { "a1", "a2" }, "b", "c", "d");
          }
      }
      
      class StringCollection
      {
          public readonly bool IsCollection;
          public string[] Values;
      
          public StringCollection(string value)
          {
              Values = new[] { value };
              IsCollection = false;
          }
      
          public StringCollection(string[] values)
          {
              Values = values;
              IsCollection = true;
          }
      
          public static implicit operator StringCollection(string value)
          {
              return new StringCollection(value);
          }
      
          public static implicit operator StringCollection(string[] values)
          {
              return new StringCollection(values);
          }
      }
      

      【讨论】:

        【解决方案4】:

        您可以尝试将paramsjagged array 一起使用

        public static void MyMethod(params string[][] s1)
        {
        }
        

        并稍微更新方法调用

        MyMethod(new[] { "a", "b" }, new[] { "s", "m" });
        MyMethod(new[] { "a", "p" }, new[] { "u" }, new[] { "v", "p" }, new[] { "e" });
        MyMethod(new[] { "a", "b", "b", "d" });
        

        请记住,在最后一行中,您传递的只是一个一维数组,您应该在方法中正确管理它

        但是,它看起来不够可读,IMO。最好有几个不同签名的重载

        public static void MyMethod(params string[][] s1)
        {
        }
        public static void MyMethod(params string[] s1)
        {
        }
        

        那么你可以将最后一个方法调用为MyMethod("a", "b", "b", "d");,而无需声明数组。

        不幸的是,您无法避免使用带有new 运算符的数组声明,target-typed new expression 将出现在下一个 C# 版本中

        【讨论】:

          猜你喜欢
          • 2014-02-15
          • 1970-01-01
          • 2012-04-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多