修改辅助类中的方法

时间:2016-06-06 06:29:34

标签: c#

最近我遇到了一个我不太确定的问题。场景是:

假设我们有一个辅助类:H和辅助类M1(int a,int b,int c)中的方法接受三个参数。有三个类使用这种方法:C1,C2,C3。

现在,我们需要另一个类C4,它也使用方法M1并将传递四个参数而不是三个。

那么,我们如何解决这个问题。

我们需要扩展方法吗?

2 个答案:

答案 0 :(得分:2)

您可以使用默认参数重载M1()方法:

public static void M1(int a, int b, int c, int? d = null)
{
    // working with a, b, c

    if (d == null)
        return;

    var dValue = (int)d; // casting the nullable int to int to work with

    // use the d parameter
}

在C1,C2,C3中你会打电话:

H1(1, 2, 3);
在C4中你会打电话给:

H1(1, 2, 3, 4);

注意:int?生成输入参数nullable,因此您可以将其设置为null。这样您就不必选择一个数字作为默认参数(也可以有意地传递)。

答案 1 :(得分:1)

您可以使用默认参数,但是存在C1,C2和C3也通过4个参数获得重载的问题,C4将通过3个参数获得重载。你提出问题的方式,我猜这没有意义(尤其是带有3个参数的C4通常在现实设计中没有意义)。

前进的方向是引入受保护的成员并转发呼叫。基本上你的代码看起来像这样:

public class BaseClass 
{
    protected void H1B(int a, int b, int c, int d) { ... }
}

public class BaseClassFor3 : BaseClass
{
    public void H1(int a, int b, int c) { H1B(a,b,c,0); } // forward call
}

public class C1 : BaseClassFor3 {} // etc
public class C2 : BaseClassFor3 {} // etc 
public class C3 : BaseClassFor3 {} // etc

public class C4 : BaseClass
{
    public void H1(int a, int b, int c, int d) { H1B(a,b,c,d); } // forward call
}

添加可空或参数

现在这是来自@KAI的棘手问题:在什么情况下你添加int? d或另一个重载?到此为止。

根据经验,我总是试图保持一个类的功能独立于其他类的功能。这基本上意味着如果你有C4,基类中的代码不应该检查子类隐含的条件(例如C4)。

所以让我们说我们会有这个:

public void H1(int a, int b, int c, int? d) //...

通常这意味着在某个地方我们会得到这个代码:

if (d.HasValue) 
{ 
    // handle something that's specific for C4
}

因为这打破了独立思想,我永远不会那样做。

现在有两种选择:

  1. H1调用实现共享相同的名称(因为在使用该类时这很容易理解),但在其他方面几乎没有共同点。
  2. H1调用实现共享许多相同的代码(除了名称)。
  3. 作为(1)的例子:如果你熟悉f.ex. PDF应用程序,C1-C4实际上可能是4x4矩阵上的向量运算。在这种情况下,一些操作有3个操作数,其他操作有4个操作数。在省略操作数的情况下,我们通常隐含地表示0

    在这种情况下,我们添加一个带有int的公共受保护基类,并像上面一样实现它。请注意,基类的代码中没有if;它的功能在基类中是孤立的,就像它应该的那样。

    在这种情况下,我也会使用Nullable - 但是如果你开始考虑这个问题,你会注意到这些都是非常非常罕见的。

    在方案(2)中,答案是不同的。例如,假设H1在数据库中插入了一些东西。实现共享代码两次或复制粘贴它没有多大意义。隔离代码,创建单独的方法并从3/4参数实现中调用它会好得多。它可能看起来像这样:

    public void H1(int a, int b, int c, int d) 
    {
        // NOTE: this is just an example, I'd normally use an OR mapper!
    
        // Construct query using a,b,c
        string baseQuery = ConstructQuery(a,b,c);
        baseQuery += " and d = " + d.ToString();
    
        // ...
        ExecuteSql(baseQuery);
    
        // ...
    }