是否正常,遵循标准指南。。。(你明白了)有一个像下面这样的方法:
public void Method(IList<int> test)
{
test.Add(1);
}
不知怎的,我期望从方法签名中得到一些信息,即参数将被修改(如ref或out),或者类似于约定的返回与返回值相同的列表,类似于:
public IList<int> Method(IList<int> test)
{
test.Add(1);
return test;
}
你觉得怎么样?提前谢谢。
我个人尽量避免使用这类方法,并尽量使用更"函数"的风格,即方法接受一些输入并返回输出。当然,有时实际更改方法中的列表是最有意义的,但我会尝试非常明确地使用方法名称。
顺便说一句,第二个例子是两个世界中最糟糕的:它不仅修改了参数,而且通过返回值来隐藏这一事实。这绝对是一个代码气味。
是的,在C#和Java世界中完全可以。
这是一件总是让我从C++背景中感到有点不安的事情。在C++中,作为库的作者,我可以将方法参数标记为const
,以表明您(客户端代码)可以安全地向我提供您的数据,而我(库)则承诺在不干扰数据的情况下使用它
在C#和Java中你不会得到这些。其理念是,为了提高效率,你可以在各处传递参考资料,而不需要复制,但这样做,你就允许图书馆对你的数据进行更改。通常情况下,这效果很好,因为除非在类文档中写入数据,否则库不会接触到您的数据;然而,编译器并没有强制保证这一点。
如果你——客户端代码作者——真的对你的数据在移交给库时被修改感到偏执,那么在将数据移交给我的库之前,你就有责任复制或克隆你的数据。在这样做的过程中,您将承担制作副本的运行时惩罚。
public IList<int> Method(IList<int> test)
{
test.Add(1);
return test;
}
类型IList<int>
实际上已经表示您需要IList<T>
方法(如Add
),而这些方法在IEnumerable<T>
中不存在。
当然,您需要为该方法提供一个有用的名称,并在其他开发人员可以公开该方法的情况下提供XML文档,从而记录该方法的实际功能。
我认为,如果你的函数在代码中的某个地方与索引操作(尤其是数组)相连,你可能会到达超出范围的异常
是的,如果开发者知道它有很好的文档注释,或者流程用一个很好的描述性方法名称让它知道。使用名称Method(List)
不是。
public void FindMoreIds(IList<int> ids)
{
...
ids.Add(...);
...
}
现在这是有效的,因为通过签名来修改集合是有意义的。您所做的不想做的是设置如下内容:
public IList<int> FindMoreIds(IList<int> ids)
{
...
ids.Add(...);
...
return ids;
}
开发人员会认为他们传递的原始集合是未修改的。
如果您不打算修改集合,当然还有其他解决方案可供使用。您可以使用IEnumerable<T>
或数组。