是否有可能重载Func <t,tresult =“”>和Func <t1,t2,=“”tresult =“”>具有相同的名称?</t1,> </t,>

时间:2012-02-26 12:45:23

标签: c# delegates overloading func

首先,我知道我可以定义两个重载的辅助方法来完成我需要的工作(或者甚至只是定义两个具有不同名称的Func&lt;&gt;),但这些只能由一个公共方法使用,所以我我正在探索通过使用相同名称来定义两个也过载的本地Func&lt;&gt;的方法。举个例子:

string DisplayValue(int value)
{ return DisplayValue(value, val => val.ToString()); }

string DisplayValue(int value, Func<int, string> formatter)
{ return (value < 0) ? "N/A" : formatter(value); }

我需要在我的公共方法中多次调用一个或另一个版本来自定义格式化特殊值,所以我认为我可以将上述内容“翻译”成这样的内容:

Func<int, Func<int, string>, string> displayValue =
    (value, formatter) => (value < 0) ? "N/A" : formatter(value);

Func<int, string> displayValue =
    value => displayValue(value, val => val.ToString());

即使我输入它,我也知道我无法声明两个具有相同名称的委托标识符,即使它们是不同的类型。这比使用Func&lt;&gt; s实现超载的死机更具学术性,但我猜他们不能做任何事情,对吧?

我想你不能做这样的事情:

Func<string, params object[], string> formatArgs =
    (format, args) => string.Format(format, args);

4 个答案:

答案 0 :(得分:6)

不,你不能超载变量。这是你想要做的。

仅从用例开始:

 DisplaywWithoutFormatter(displayValue);
 DisplaywWithFormatter(displayValue);

由于没有涉及参数,编译器无法可靠地区分这两者。

答案 1 :(得分:1)

您可以通过为格式化程序声明optional argument的委托来实现您的目标:

delegate string DisplayValue(int value, Func<int, string> formatter = null);

static void Main(string[] args)
{
    DisplayValue displayValue = (value, formatter) =>
        formatter == null ?
            value.ToString() :
        value < 0 ?
            "N/A" :
            formatter(value);

    string s1 = displayValue(33);
    string s2 = displayValue(33, i => i.ToString("D4"));

    // s1: "33"
    // s2: "0033"
}

答案 2 :(得分:1)

您可以使用String.Format()函数显式定义案例的委托类型:

delegate string FormatDelegate(string formatString, params object[] @params);

对于带有可选参数的.Net Framework,您可以使用@Douglas的答案。

但是如果您使用.Net Framework 3.5(没有可选参数),那么您可以像这样定义DisplayValue委托:

delegate string DisplayDelegate(int value, params Func<int, string>[] formatters);

以下是使用代理人的示例:

delegate string DisplayDelegate(int value, params Func<int, string>[] formatters);

delegate string FormatDelegate(string formatString, params object[] @params);

static void Main()
{
    FormatDelegate formatDelegate = (format, args) => string.Format(format, args);

    Console.WriteLine(formatDelegate("String with params: {0} {1}", 1, "something")); 
    //Output: "String with params: 1 something"

    Console.WriteLine(formatDelegate("String without params"));  
    //Output: "String without params"

    DisplayDelegate displayValue  = 
        (value, formatter) =>
            formatter.Length == 0 
                ? value.ToString() 
                : value < 0 
                    ? "N/A" 
                    : formatter[0](value);

    Console.WriteLine(displayValue(33));                         // "33"
    Console.WriteLine(displayValue(33, v => v.ToString("D4")));  // "0033"
    Console.WriteLine(displayValue(-33));                        // "-33"  
    Console.WriteLine(displayValue(-33, v => v.ToString("D4"))); // "N/A"
}

答案 3 :(得分:0)

我认为你可以通过创建一个带有重载operator()的{​​{3}}来在C ++中做这样的事情。但是在C#中,你只有代表,他们不能超载。