2011-10-07 68 views
29

我有以下代码:参数操作<T1, T2, T3>其中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 
} 

可选参数3参数的注意。

现在有很多原因需要将MyMethod方法的代码提取到它自己的类中,但是我无法从中提取ProtectedMethod,因为所有继承自此类的类都需要保留更改小而孤立。所以我想我可以在新类中使用与ProtectedMethod具有相同签名的Action委托。

的问题是,如果我声明的委托是这样的:

protected readonly Action<IEnumerable<string>, string, int> m_ProtectedMethod; 

提取的代码不会因为它说的方法只被调用带有两个参数的喜欢。

如果我声明,像这样的委托:

protected readonly Action<IEnumerable<string>, string> m_ProtectedMethod; 

当我把它作为参数传递给新的班级不喜欢它是因为该方法被定义为具有三个参数而不是两个。

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

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

+0

没有关系,但看起来类似的东西:http://stackoverflow.com/questions/707780/is-there-a-reasonable-approach-to-default-type-parameters-in-c-sharp-泛型 – nawfal

回答

29

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

运行时不知道可选参数,所以当调用它时,您不能创建一个插入可选参数的委托。

相反,你需要声明一个自定义的委托类型有一个可选的参数:

public delegate void MyDelegate(IEnumerable<string> param1, string param2, int param3 = 1); 

调用此委托时,你就可以省略了第三个参数,无论方法的声明(S ) 它包含。

+2

可以输入参数是可选的吗? –

+0

@Joel:你什么意思? – SLaks

+2

@JoelCoehoorn - 没有 - 泛型创建新类型 –

1

这将取决于m_ProtectedMethod将如何被消耗掉,但我发现我自己的情况,在这里我用一个比另一个更超负荷的妥协。

只需定义更简单(具有较少通用参数)动作<>变量,它调用更复杂的提供的Action变量方法。这可以通过以下方式完成:(i)本地使用范围;或(ii)分配行动财产或对象建设后的对象范围。

因为没有变量/属性重载这样的事情,所以需要两个不同的名称,以生成两个相关的Action变量。

例如: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个后缀,这样在消费时更简单的重载具有更基本的变量名称。

相关问题