简体   繁体   English

减少代码重复:调用具有略微不同签名的函数

[英]Reducing Code Repetition: Calling functions with slightly different signatures

Suppose I have two functions which look like this: 假设我有两个看起来像这样的函数:

public static void myFunction1(int a, int b, int c, string d)
{
    //dostuff
    someoneelsesfunction(c,d);
    //dostuff2
}

public static void myFunction2(int a, int b, int c, Stream d)
{
    //dostuff
    someoneelsesfunction(c,d);
    //dostuff2
}

What would be a good way to avoid repeated dostuff? 什么是避免重复dostuff的好方法?

Ideas I've thought of, but don't like: 我想过的想法,但不喜欢:

  1. I could make d an object and cast at runtype based on type, but this strikes me as not being ideal; 我可以根据类型制作一个对象并按照runtype进行投射,但这让我觉得不理想; it removes a type check which was previously happening at compile time. 它删除了以前在编译时发生的类型检查。
  2. I could also write a private helper class that takes an object and write both signatures as public functions. 我还可以编写一个私有帮助器类,它接受一个对象并将两个签名都写为公共函数。
  3. I could replace dostuff and dostuff2 with delegates or function calls or something. 我可以用委托或函数调用等替换dostuff和dostuff2。

Just refactor "doStuff" and "doStuff2" into separate methods. 只需将“doStuff”和“doStuff2”重构为单独的方法即可。

They're obviously doing "stuff" that's separate from the "someoneelsesfunction" method, so they should be separate methods anyways. 他们显然做的“东西”与“personelsesfunction”方法分开,所以它们应该是不同的方法。 Each method should have one task, ideally. 理想情况下,每种方法都应该有一个任务。

This is even a supported refactoring in Visual Studio - just highlight the code in "dostuff", and right click, and choose Refactor->Extract Method. 这甚至是Visual Studio中支持的重构 - 只需突出显示“dostuff”中的代码,然后右键单击,然后选择Refactor-> Extract Method。

I might do something like this: 我可能会这样做:

public static void myFunction1(int a, int b, int c, string d)
{
    //dostuff
    someoneelsesfunction(c, d);
    //dostuff2
}

public static void myFunction2(int a, int b, int c, Stream d)
{
    string str = d.ReadEntireString(); // no such method, but basically
        // whatever you need to do to read the string out of the stream
    myFunction1(a, b, c, str);      
}

... and change the name of both functions to MyFunction (to take advantage of overloading, which is the same thing someoneelsesfunction() is doing. ...并将两个函数的名称更改为MyFunction (以利用重载,这与someoneelsesfunction()正在做的事情相同。

NOTE: this solution would be impractical if the string contained in the Stream is ginormous. 注意:如果Stream中包含的字符串是巨大的,那么此解决方案将是不切实际的。 If so, you might want to do this the other way around: read the string d into a stream and call the override with the stream parameter. 如果是这样,您可能希望以相反的方式执行此操作:将字符串d读入流并使用stream参数调用override。

Use Action to customize what a function does in some specific place. 使用Action可以自定义函数在某些特定位置执行的操作。

public void myF1(int a, int b, int c, int d)
{
     internalF(a, b, { someelse1(c, d); }); 
}
public void myF2 (int a, int b, int c, Stream d)
{
     internalF(a, b, { someelse2(c, d); });
}
private void internalF (int a, int b, Action action)
{
    // dostuff
    action();
    // dostuff2
}

Eventually you can create 最终你可以创建

public static void myFunction3(int a, int b, int c, Stream d, string e)

which will be called from function1 and function2 with d or e set to null. 这将从function1和function2调用,d或e设置为null。 Then function3 would distinguish between calls to someoneelsesfunction(c,d). 然后function3将区分对某人功能的调用(c,d)。 It is a possible solution, but for desperates :) 这是一个可能的解决方案,但绝望:)

I'd start by extracting methods DoStuff and DoStuff2 and calling them from both functions. 我首先提取DoStuff和DoStuff2方法并从两个函数中调用它们。

You could then start to get funky by wrapping the block in another method and passing the someoneelsefunction to use to that method, but thats a step too far imho. 然后,您可以通过将块包装在另一个方法中并将单个函数函数传递给该方法来开始变得时髦,但这样做太过分了。 you want things to be easy to read and change as well as not containing repetition. 你希望事物易于阅读和改变,而不是重复。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM