【问题标题】:Is it normal (ok) to modify a collection (array, whatever) passed as parameter of a method? [closed]修改作为方法参数传递的集合(数组等)是否正常(可以)? [关闭]
【发布时间】:2014-02-12 16:15:38
【问题描述】:

是否可以,正常,遵循标准指南......(你明白了)有一个类似以下的方法:

public void Method(IList<int> test)
{
    test.Add(1);
}

不知何故,我希望从方法签名中获得一些信息,即参数将被修改(如 ref 或 out)或约定如返回与返回值相同的列表,例如:

public IList<int> Method(IList<int> test)
{
    test.Add(1);
    return test;
}

你怎么看? 提前致谢。

【问题讨论】:

  • 方法签名可以隐式提供此信息:如果您不打算修改参数,则应将其类型降级为只读类型(在本例中为IEnumerable&lt;int&gt;)。一般来说,最好使用“纯”方法(没有任何副作用),但当然,当你想做煎蛋时,你必须打碎一些鸡蛋。
  • 我个人尽量避免在公共方法中出现类似的副作用,除非其意图非常明显。
  • @Jon,问题是您有时需要一个索引器,而 .Net 不提供任何带有索引器的只读接口(很遗憾)。
  • @Grzenio: IReadOnlyList&lt;T&gt;?
  • @Jon,.NET Framework 4.5。我的公司需要数年才能升级:(不过感谢您让我知道,这绝对是朝着正确方向迈出的一步!

标签: c# .net parameters parameter-passing


【解决方案1】:

我个人尽量避免使用这些方法,并尝试坚持一种更“功能性”的风格,即方法接受一些输入返回输出。当然,有时在方法中实际更改列表是最有意义的,但是我试图对方法名称非常明确。

附带说明,您的第二个示例是两全其美:它不仅修改了参数,而且通过返回值隐藏了这一事实。这绝对是代码味道。

【讨论】:

    【解决方案2】:

    是的,在 C# 和 Java 世界中完全没问题。

    对于来自 C++ 背景的我来说,这是一件总是让我有点不安的事情。在 C++ 中,作为库作者,我可以将方法参数标记为const,以表明您——客户端代码——可以安全地给我你的数据,而我——库——承诺在不打扰它的情况下使用它。

    你不会在 C# 和 Java 中得到它。其理念是,您可以在各处传递参考资料,而无需制作副本以提高效率,但这样做,您就允许图书馆对您的数据进行更改。通常,这很有效,因为除非在类文档中写入库,否则库不会触及您的数据;但是,对此没有编译器强制保证。

    如果您(客户端代码作者)在将数据移交给库时确实担心您的数据会被修改,那么您就有责任在将数据移交给我的库之前复制或克隆您的数据。这样做会导致制作副本的运行时损失。

    【讨论】:

      【解决方案3】:
      public IList<int> Method(IList<int> test)
      {
          test.Add(1);
          return test;
      }
      

      IList&lt;int&gt; 类型实际上已经表明您需要 IEnumerable&lt;T&gt; 中不存在的 IList&lt;T&gt; 方法(例如 Add)。

      当然,您需要为方法提供有用的名称以及 XML 文档(如果其他开发人员可以公开使用),来记录该方法的实际作用。

      【讨论】:

        【解决方案4】:

        我认为,如果您在代码中的某个功能与索引操作相关联(尤其是对于数组),您可能会遇到超出范围异常

        【讨论】:

          【解决方案5】:

          是的,如果开发人员使用漂亮的 doc cmets 知道它,或者进程使用漂亮的描述性方法名称使其知道。不使用名称Method(List)

          public void FindMoreIds(IList<int> ids)
          {
               ...
               ids.Add(...);
               ...
          }
          

          现在这行得通,因为通过查看签名来修改集合是有道理的。你想做的就是这样设置:

          public IList<int> FindMoreIds(IList<int> ids)
          {
               ...
               ids.Add(...);
               ...
               return ids;
          }
          

          开发人员会认为他们传递的原始集合不会被修改。

          如果您不打算修改集合,当然可以使用其他解决方案。您可以改用IEnumerable&lt;T&gt; 或数组。

          【讨论】:

            猜你喜欢
            • 2011-10-31
            • 1970-01-01
            • 2013-11-13
            • 1970-01-01
            • 1970-01-01
            • 2010-10-05
            • 2023-03-09
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多