C# 改变方法内的参数值,这是反模式吗?

C# 改变方法内的参数值,这是反模式吗?,c#,anti-patterns,C#,Anti Patterns,像这样的 public void MyMethod(object parameter) //.... BuildSomething(parameter); BuildLayers(parameter); BuildOtherStuff(parameter); } public void BuildSomething(object parameter) { //... parameter.SomeProperty = "sadsd"; //... } 如果这是一

像这样的

public void MyMethod(object parameter)
//....
    BuildSomething(parameter);
    BuildLayers(parameter);
    BuildOtherStuff(parameter);
}

public void BuildSomething(object parameter)
{
//...
    parameter.SomeProperty = "sadsd";
//...
}
如果这是一个反模式,它叫什么? 问题(可能)是您正在隐式更改参数并使用更改后的值。
我只想知道这个反模式是什么

谢谢

这是一个好主意

这些通常不好,被认为是一种代码气味,因为它使人们很难对代码进行推理和理解

然而,这种模式有时是有用的


C#对
ref
out
关键字进行编码,以明确表明一种方法预期会产生副作用。

我有不同的观点

尽管在调试过程或代码可读性中更改参数值可能会带来一些小问题,但我称这种做法为“反模式”是没有意义的

基于Java或C#等现代OO语言的设计,我支持这样的想法,即如果更改参数值是丑陋的、错误的或不可取的,那么他们应该将定义的类型参数作为实例的副本,而不是引用


我不同意Oded所说的,我认为ref或out关键字应该只在您真正想要更改整个实例值的上下文中使用,完全替换它。使用其中一个关键字只是为了告诉“嘿,伙计,参数值在执行堆栈期间可能会更改”,这听起来有点粗心。如果你的一个客户看到了函数签名,并且真的相信他可以替换整个东西怎么办?(在非预期行为的情况下)。

假设
参数的类型实际上不是
对象
,而是包含名为
SomeProperty
的可写属性或字段的类类型,那么当方法输入时,
参数
的值将是某个对象的标识(比如说,自程序启动以来创建的第459192个对象)。据我所知,该参数的值(意味着它引用的对象的标识)在整个方法中都将保持不变


更改传入参数的值(例如说
parameter=someOtherObject
)可能是一种代码气味,除非方法足够小,可以清楚地看到发生了什么。

我相信,只要方法名称说明了它是什么,这就可以了does@sll这就是问题所在。它要么没有说明它的功能,要么方法名是BuildSomethingwithLayersBuiltFromOtherStuff。@knaki02我不这么认为……定义非常清楚:
一个函数或表达式被称为有副作用,如果它除了返回一个值之外,还修改了一些状态,或者与调用函数或外部世界有一个可观察的交互
。就我所知,参数已更改的事实是与外部世界的一个可观察的交互,那么“in”呢除了返回值“?Void方法没有。这是一个副作用,因为它会更改参数,并且不清楚该方法是否会执行此操作。不要介意一些学者说,Void DoSomethingTo(arg)不是DoSomethingWith(arg)。返回一个void结果并不意味着副作用,正如非void返回类型不意味着纯度一样。恰好void只包含一个值(NULL),因此它不包含运行时信息(与包含1位的bools不同)。传递voids很有用的一个地方是在类型上实现参数化接口(即使用存在类型)。例如,我们的接口可能在“Config”类型上参数化,并要求我们实现函数“getConfig:void->Config”;如果我们的实现是不可配置的,我们可以使用void作为Config。我更希望根据op的示例看到ref或out作为MyObject DoSomethingWith(MyObject oldObj);要清楚得多。作为一个基本的维护编码员,我讨厌副作用。如果是out或ref,他们可以替换整个东西,他们知道,代码应该能够处理这一点。根据我的经验,不相信该方法会改变参数是一个更大的问题,应该只改变传递参数的类对我来说,这是一种教条和货物崇拜的味道