首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >参数Action<T1,T2,T3>,其中T3可以是可选的

参数Action<T1,T2,T3>,其中T3可以是可选的
EN

Stack Overflow用户
提问于 2011-10-07 17:02:05
回答 3查看 16.8K关注 0票数 33

我有以下代码:

代码语言:javascript
复制
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相同的签名,以获得一个ProtectedMethod委托。

问题是,如果我这样宣布代表:

代码语言:javascript
复制
protected readonly Action<IEnumerable<string>, string, int> m_ProtectedMethod;

提取的代码不喜欢它,因为它说方法只使用两个参数调用。

如果我这样宣布代表:

代码语言:javascript
复制
protected readonly Action<IEnumerable<string>, string> m_ProtectedMethod;

当我将它作为参数发送到新的类时,它也不喜欢它,因为方法被定义为有三个参数而不是两个参数。

到目前为止,解决这个问题的唯一方法是创建一个重载版本的ProtectedMethod,以消除可选参数。

这是唯一的选择,还是有另一种方法,因为现在首选的选择是有可选的参数而不是重载的方法?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-10-07 17:04:05

可选参数是方法或委托参数的属性。当在编译时调用具有已知可选参数的签名(方法或委托)时,编译器将在调用站点插入可选参数值。

运行时不知道可选参数,因此您无法生成在调用可选参数时插入可选参数的委托。

相反,您需要使用可选参数声明自定义委托类型:

代码语言:javascript
复制
public delegate void MyDelegate(IEnumerable<string> param1, string param2, int param3 = 1);

当调用此委托时,您将能够省略第三个参数,而不管它包含的方法的声明是什么。

票数 36
EN

Stack Overflow用户

发布于 2014-09-06 03:03:02

这将取决于如何使用m_ProtectedMethod,但我在自己的情况下找到了一个折衷方案,在这种情况下,我使用一种重载比另一种更多。

简单地说,定义了一个更简单(泛型参数较少)的Action<>变量,它调用了更复杂的提供的Action方法。这可以在以下两种情况下实现:(一)本地使用范围;或(二)在分配Action或对象构造时的对象范围。

因为不存在变量/属性重载的情况,因此需要两个不同的名称,用于生成两个相关的Action变量。

本地范围(可能不是最适合您的场景)

代码语言:javascript
复制
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:对象范围

代码语言:javascript
复制
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后缀,这样,在消费时,更简单的重载具有更基本的变量名。

票数 1
EN

Stack Overflow用户

发布于 2018-09-12 20:10:08

希望能帮助其他人更好地实现重载,并将其与(面向委托的)策略模式相结合。

代码语言:javascript
复制
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);
    }
}

用法:

代码语言:javascript
复制
new OverloadExample().Implementation(9001);
new OverloadExample().Implementation(9001, false);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7690482

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档