【问题标题】:Change value of parameter inside method, is this an anti-pattern?更改方法内部参数的值,这是反模式吗?
【发布时间】:2012-12-28 12:37:23
【问题描述】:

像这样的

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

public void BuildSomething(object parameter)
{
//...
    parameter.SomeProperty = "sadsd";
//...
}

如果这是一个反模式,它叫什么? 问题(可能)是您正在隐式更改 参数 并使用更改后的值。
我只想知道这个反模式是什么

谢谢

【问题讨论】:

  • 我相信只要方法名称说明它的作用就可以了
  • @sll 这就是这个倒下的地方。它要么没有说明它的作用,要么方法名称是 BuildSomethingwithLayersBuiltFromOtherStuff。

标签: c# anti-patterns


【解决方案1】:

这是一个side effect

这些通常不好,被认为是代码异味,因为它使推理和理解代码变得困难。

但是,这种模式有时很有用。

C# 编码了refout 关键字特别,以表明一种方法预计会产生副作用。

【讨论】:

  • @knaki02 我不这么认为...定义很明确:a function or expression is said to have a side effect if, in addition to returning a value, it also modifies some state or has an observable interaction with calling functions or the outside world.
  • 据我所知,参数发生了变化,这是与外界的可观察到的交互
  • “除了返回一个值”呢? void 方法没有。
  • 这是一个副作用,因为它改变了参数并且不清楚这就是该方法的作用。别管有些学者怎么说,void DoSomethingTo(arg) 不是 DoSomethingWith(arg)。
  • 返回 void 结果并不意味着副作用,就像非 void 返回类型并不意味着纯度一样。它只是碰巧 void 只包含一个值(NULL),因此它不包含运行时信息(与包含 1 位的布尔值不同)。传递 void 的一个有用的地方是实现一个在类型上参数化的接口(即使用存在类型)。例如,我们的接口可能被参数化为“Config”类型,并要求我们实现一个函数“getConfig : void -> Config”;如果我们的实现是不可配置的,我们可以使用 void 作为 Config。
【解决方案2】:

我有不同的观点。

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

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

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

【讨论】:

  • 我宁愿看到 ref 或 out 基于 op 的示例 MyObject DoSomethingWith(MyObject oldObj);清楚了很多。作为本质上的维护编码员,我讨厌副作用。如果它是 out 或 ref,他们可以替换整个东西,他们知道,代码应该处理它。根据我的经验,不相信该方法会改变参数是一个更大的问题,它应该只改变参数传递给的类。
  • 这对我来说是教条和货物崇拜的味道en.wikipedia.org/wiki/Argument_from_authority
【解决方案3】:

假设parameter的类型不是真正的object,而是一个类类型,其中包含一个名为SomeProperty的可写属性或字段,那么当方法进入时,parameter的值将是某个对象的身份(例如,自程序开始以来创建的第 459,192 个对象)。据我所知,该参数的值(即它所引用的对象的身份)在整个方法中将继续保持相同。

更改传入参数的值(例如说parameter = someOtherObject)可能是代码异味除非该方法足够小以至于很明显发生了什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    • 2013-04-23
    • 1970-01-01
    相关资源
    最近更新 更多