最近我遇到了一个我不太确定的问题。场景是:
假设我们有一个辅助类:H和辅助类M1(int a,int b,int c)中的方法接受三个参数。有三个类使用这种方法:C1,C2,C3。
现在,我们需要另一个类C4,它也使用方法M1并将传递四个参数而不是三个。
那么,我们如何解决这个问题。
我们需要扩展方法吗?
答案 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)的例子:如果你熟悉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);
// ...
}