参数动作 其中T3可以是可选的
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了参数动作 其中T3可以是可选的相关的知识,希望对你有一定的参考价值。
我有以下代码:
public static MyMethod()
{
...Do something
ProtectedMethod(param1, param2);
...Do something
}
protected static void ProtectedMethod(IEnumerable<string> param1, string param2, int param3 = 1)
{
... Do something
}
注意可选的param3参数。
现在由于很多原因,我需要将MyMethod方法的代码提取到它自己的类中,但我不能用它提取ProtectedMethod,因为所有继承自这个的类都需要保持变化小而孤立。所以我想我可以在新类中使用与ProtectedMethod相同签名的Action <>委托。
问题是如果我像这样声明委托:
protected readonly Action<IEnumerable<string>, string, int> m_ProtectedMethod;
提取的代码不喜欢它,因为它表示只使用两个参数调用该方法。
如果我像这样声明代表:
protected readonly Action<IEnumerable<string>, string> m_ProtectedMethod;
当我将它作为参数发送到新类时,它不喜欢它,因为该方法被定义为具有三个参数而不是两个参数。
到目前为止,我想到解决这个问题的唯一方法是创建一个重载版本的Protected Method来消除可选参数。
这是唯一的选择还是有另一种方法,因为现在首选的选择是使用可选参数而不是重载方法?
可选参数是方法或委托参数的属性。在编译时调用具有已知可选参数的签名(方法或委托)时,编译器将在调用点处插入可选参数值。
运行时不知道可选参数,因此您无法在调用时插入可选参数。
相反,您需要使用可选参数声明自定义委托类型:
public delegate void MyDelegate(IEnumerable<string> param1, string param2, int param3 = 1);
调用此委托时,无论其包含的方法声明如何,您都可以省略第三个参数。
这将取决于m_ProtectedMethod
将如何消耗,但我发现在我自己的情况下妥协,我使用一个重载比另一个更多。
只需定义一个更简单(具有更少通用参数)的Action <>变量,它调用更复杂的Action变量方法。这可以在(i)使用的当地范围内完成;或(ii)转让行动财产或物体构造的对象范围。
因为没有变量/属性重载这样的东西,所以需要两个不同的名称,用于生成两个相关的Action变量。
EG i:本地范围(可能不是最适合您的场景)
public MyMethod(Action<IEnumerable<string>, string, int> m_ProtectedMethod2)
{
Action<IEnumerable<string>, string> m_ProtectedMethod = (p1,p2) => {
m_ProtectedMethod2(p1,p2,1); //The value 1 is the default 3rd parameter
}
...Do something
m_ProtectedMethod(param1, param2);
...Do something
...If something
m_ProtectedMethod2(param1, param2, param3); //Calling the more complex form directly
...Do something
}
EG ii:对象范围
private Action<IEnumerable<string>, string, int> m_ProtectedMethod2 = null;
private Action<IEnumerable<string>, string> m_ProtectedMethod = null;
protected Action<IEnumerable<string>, string, int> ProtectedMethod
{
get { return m_ProtectedMethod2; }
set {
m_ProtectedMethod2 = value;
m_ProtectedMethod = (p1,p2) => {
m_ProtectedMethod2(p1,p2,1); //The value 1 is the default 3rd parameter
}
}
}
public MyMethod()
{
...Do something
m_ProtectedMethod(param1, param2);
...Do something
...If something
m_ProtectedMethod2(param1, param2, param3); //Calling the more complex form directly
...Do something
}
请注意,在这两种情况下,我将默认设置值设计为更加笨拙的命名变量,具有2个后缀,这样在使用时,更简单的重载具有更基本的变量名称。
希望通过我发现的更优雅的重载实现与(委托导向的)策略模式相结合来帮助其他人。
public class OverloadExample {
private Action<int, bool> _implementation;
public OverloadExample() {
_implementation = defaultImplementation;
}
public OverloadExample(Action<int, bool> implementation) {
_implementation = implementation;
}
protected void defaultImplementation(int aInt, bool aBool) {
//
}
public void Implementation(int someInt, bool someBool = true) {
_implementation(someInt, someBool);
}
}
用法:
new OverloadExample().Implementation(9001);
new OverloadExample().Implementation(9001, false);
以上是关于参数动作 其中T3可以是可选的的主要内容,如果未能解决你的问题,请参考以下文章
传递给 PDOStatement::bindParam() 的参数名称的前导冒号是可选的吗?