当前位置:  开发笔记 > 编程语言 > 正文

在C#中处理可变数量的输出参数,减少代码重复

如何解决《在C#中处理可变数量的输出参数,减少代码重复》经验,为你挑选了4个好方法。

我正在尝试编写一个用数组内容填充字符串的函数,或者将它们设置为null.字符串的数量可以变化,我不想添加像它们一样的要求都是同一个数组或类的一部分.

在C#中你无法组合paramout.因此,这样做的唯一方法似乎是重载这样的方法:

    public void ParseRemainders(string[] remainders, out string p1)
    {
        p1 = null;
        if ((remainders != null) && (remainders.Length > 0))
            p1 = remainders[0];
    }

    public void ParseRemainders(string[] remainders, out string p1, out string p2)
    {
        p1 = null;
        p2 = null;
        if (remainders != null)
        {
            ParseRemainders(remainders, out p1);
            if (remainders.Length > 1)
                p2 = remainders[1];
        }
    }

    public void ParseRemainders(string[] remainders, out string p1, out string p2, out string p3)
    {
        p1 = null;
        p2 = null;
        p3 = null;
        if (remainders != null)
        {
            ParseRemainders(remainders, out p1, out p2);
            if (remainders.Length > 2)
                p3 = remainders[2];
        }
    }

    .... and on forever ....

如何避免所有这些代码重复,理想情况下接受任意数量的参数?


编辑:这很有用,因为您可以这样做,ParseRemainders(remainders, out inputFileName, out outputFileName, out configFileName)然后避免必须手动执行

if (remainder.Length > 0) inputFileName = remainder[0];
if (remainder.Length > 1) outputFileName = remainder[1];
if (remainder.Length > 2) configFileName = remainder[2];
...

对不起,如果不清楚,我有一个特定的目标,我为什么我不是简单地返回一个List<>.


结论:感谢BotondBalázs的答案,特别是暗示这被称为"阵列解构".正如他们所指出的那样,并且正如这个问题所证实的那样,在C#的当前版本中是不可能的:解构赋值 - C#中变量的对象属性



1> Eric Lippert..:

到目前为止,我会采取与任何答案不同的方法.

static class Extensions {
  public static SafeArrayReader MakeSafe(this T[] items)
  {
    return new SafeArrayReader(items);
  }
}
struct SafeArrayReader 
{
  private T[] items;
  public SafeArrayReader(T[] items) { this.items = items; }
  public T this[int index] 
  {
    get
    {
      if (items == null || index < 0 || index >= items.Length)
        return default(T);
      return items[index];
    }
  }
}

在那里,现在你有一个数组,它给你一个默认值而不是抛出:

var remainder = GetRemainders().MakeSafe();
var input = remainder[0];
var output = remainder[1];
var config = remainder[2];

十分简单.您对数据类型的语义有问题吗?创建一个更好的数据类型,封装所需的语义.


@Pikoh:负面结果是:如果您在不仔细考虑的情况下添加新属性,则将值分配给完全意外的变量,但程序继续编译并运行.此外,保护财产和私有财产等不寻常但合法的案件呢?如果你将你的类重构为两个类,base和derived,一个有一半属性,另一个有另一半,那会怎么样?解决方案继续有效吗?等等.请记住,**代码更改**.不要只设计正确的代码*现在*; 面对变化*使其变得强大*.

2> Botond Baláz..:

如果我理解正确,您的用例将如下所示:

var remainders = new[] { "a", "b", "c" };
string a, b, c;
ParseRemainders(remainders, a, b, c); // after this, a == "a", b == "b" and c == "c"

您希望在C#中使用的功能称为数组解构,就像在JavaScript中一样:

var remainders = ["a", "b", "c"];
var [a, b, c] = remainders; // after this, a == "a", b == "b" and c == "c"

不幸的是,据我所知,

这不能用C#以一般方式解决.

C#7虽然会有元组解构.



3> Andy Korneye..:

好吧,你可以改变你的方法

public IEnumerable ParseRemainders(string[] remainders)
{
    var result = new List();

    ///... your logic here, fill list with your strings according to your needs

    return result;
}


谁投票似乎很奇怪:(
我认为包含"解析"的方法名称令人困惑.

4> Tim Schmelte..:

Andys方法很好,但我会返回一个string[]因为它应该与输入数组具有相同的大小,并且null如果输入数组是null:

public string[] ParseRemainders(string[] remainders)
{
    if(remainders == null) return null;
    var parsed = new string[remainders.Length];
    for(int i = 0; i < remainders.Length; i++)
        parsed[i] = ParseRemainder(remainders[i]);
    return parsed;
}

澄清一下ParseRemainder(单个方法的不同方法string):

public string ParseRemainder(string remainder)
{
    // parsing logic here...
    return "the parsing result of remainder";
}

推荐阅读
mobiledu2402851377
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有