A方法是应该从对象获取某些属性还是只取对象?

时间:2011-09-05 16:04:53

标签: c#

例如

        int GetNum(int x, int y)
              {
                  return x+y;
               }

然后致电

         z= GetNum(myobject.x, myobject.y);

         int GetNum(ClassA myobject)
              {
                  return myobject.x+myobject.y;
               }

然后致电

          z = GetNum(myobject);

5 个答案:

答案 0 :(得分:8)

传递属性值以减少类之间的耦合。在这种情况下,定义GetNum的类不需要知道ClassA

最好减少类之间的耦合\依赖关系,因为这会使您的设计更加灵活。您在哪里为方法提供复杂类型,然后提供接口,以便您可以改变传递的特定实现。这再次使您的设计更加灵活,更容易测试。

答案 1 :(得分:1)

我遵循的一般规则就是这样。该方法是否需要对象?,还是需要对象的属性值?后者使该方法更加可用(因为它不需要用户创建具有这些属性的任何类型的实例)。

你可以做的是提供过载(从而支持两者):

int GetNum(int x, int y) { return (x + y); }
int GetNum(ClassA obj) { return GetNum(obj.X, obj.Y); }

问问自己该方法的可能用例是什么,然后询问您是否确实需要传入一个包装值的实例。

考虑一下我可能有以下方法:

public void ProcessMessage(Result result)
{
  // Do something with Result.ReturnedMessage
  result.ReturnedMessage.Process(result.Target);
}

它接受理论Result类型的单个实例,但实际情况是,它只使用两个参数,因此我们可以将其重新定义为:

public void ProcessMessage(Message message, Target target)
{
  message.Process(target);
}

这使得该方法可以在更多场景中使用,当然,您可以定义一个仅从ProcessMessage(Result)路由到ProcessMessage(Message, Target)等的重载。

另一方面,如果该方法构成接口定义的一部分:

void ProcessMessage(Result result);

您不能保证实现该方法的类型不仅需要访问ReturnedMessageTarget属性。

最重要的是,考虑你的用例,以及它如何适应更大的设计。还要考虑面向未来......如何轻松地提升我们的理论Result类型?

作为一个脚注,这是一个非常类似的论点,关于使用特殊类型或基类型传递值的位置,例如:

public void DoSomething(List<string> items);
public void DoSomething(IList<string> items);
public void DoSomething(IEnumerable<string> items);

在上面的示例中,您的方法是执行明确要求List<string>类型的任何操作,还是使用IList<string>接口定义...或者如果您根本不添加任何内容。如何接受IEnumerable<string>实例。您对方法调用的专门性越低,它们的使用范围就越广泛。

答案 2 :(得分:1)

我认为这很大程度上取决于你自己的编码风格。

在我看来,如果该方法的目的是与该对象相关联,则该方法应该将对象作为参数。例如,将对象的字段格式化为漂亮的文本字符串的方法应该将对象作为其参数。

在您的示例中,该方法与该对象并不真正相关 - 它可能需要任意两个数字,它们不必包含在特定对象中以便工作,所以我认为该方法应该将属性作为参数。

但是,我不认为你选择哪种风格会产生很大的不同。

答案 3 :(得分:0)

在这种情况下,因为chibacity说GetNum不需要了解ClassA。但是,您可能会考虑实际添加GetNum作为ClassA的方法,该方法调用GetNum传递适当的值。它不一定要写,但如果你要做很多事情就可能有意义。

答案 4 :(得分:0)

我认为,就像其他一切有趣一样,答案是“它取决于”。

示例可能已经过多简化,以提供足够的上下文来正确回答问题。似乎有三种解决方案的方法: 1)int GetNum(ClassA myObject){}
2)int ClassA.GetNum(){}
3)int GetNum(int a,int b){}

在过去,我会赞成选项2,使GetNum成为ClassA的成员。 GetNum的工作方式与调用者的业务无关,或者它从何处获取信息,您(调用者)只想从ClassA对象获取数字。选项代码需要知道ClassA的内容,所以这是不合适的,即使它只使用两个getter。如果我们对上下文了解得更多,那么可能选择一个会更好。我无法从这个问题中说出来。

对提高工作中代码的可测试性非常感兴趣,尤其是遗留代码。除非已经有一个有用的单元测试框架,否则选项1和2需要ClassA的对象,并进行实例化以进行测试。为了使代码可测试(特别是如果ClassA很昂贵或实例化不切实际),我们一直在使用类似于选项3(或使其成为ClassA的静态成员)。这样,您就不需要实例化或传递难以制作的对象,并且您可以轻松添加完整的代码测试覆盖率。

一如既往,YMMV。