调用具有可选参数的Func <t1,t2,=“”t3 =“”>?

时间:2015-08-05 09:39:35

标签: c# delegates func

我有各种方法,它们有两个可选的参数,一个ConfigSourceType枚举和一个表示filePath的字符串,并返回一个&#34; IConfigFile&#34;的实例。 (根据配置文件不同)。

我试图将这些方法作为Func传递,以便我可以加载配置,但是我无法调用没有参数的委托。如果我使用Type.Missing,它仍会抱怨缺少ConfigSourceType枚举。

编辑以包含代码:

DataHandler类:

    public IConfigFile RetrieveMyConfiguration(
        ConfigurationSourceType source = ConfigurationSourceType.Live,
        string fileName = "")
    {
         /* Irrelevant */
         return new ConfigFile();
    }

主:

    private void SomeMethod()
    {  
        var dHandler = new DataHandler();
        MyConfig = LoadConfigFile(dHandler.RetrieveMyConfiguration);
    }

    public IConfigFile LoadConfigFile(
            Func<ConfigurationSourceType, string, IConfigFile> func)
    {
        IConfigFile configFile;        
        // Line below doesn't compile:
        configFile = func.Invoke(null, Type.Missing);
        return configFile;
     }

3 个答案:

答案 0 :(得分:2)

Func中没有可选项 你必须把它包起来:

public class Foo
{
    public int Boo(int A = 0, int B = 1)
    {
        return A + B;
    }
}

var foo = new Foo();

var method = (Func<int, int, int>) (foo.Boo);
var methodWrapped = (Func<int, int, int>) ((a, b) => foo.Boo(a, b));
var methodWrappedWithA = (Func<int, int>) ((a)=>foo.Boo(a));
var methodWrappedWithB = (Func<int, int>)((b) => foo.Boo(B:b));
var methodWrappedNoAorB = (Func<int>) (()=>foo.Boo());

答案 1 :(得分:1)

您无法为Func<...>指定可选参数,但您可以为自己的代表指定。

LINQPad示例显示了:

void Main()
{
    var t = new Test(XYZ);
    t();
    t(15);
}

public delegate void Test(int a = 10);

public void XYZ(int a)
{
    a.Dump();
}

输出:

10
15

但是,这意味着它是需要了解可选参数的委托的接收端,但似乎您要为方法指定委托并在发送端指定可选参数,或继承可选您在委托中包装的方法中的参数,除了创建匿名方法之外,这是不可能的:

SomeMethod((a, b) => WrappedMethod(a, b, 42));

你可以这样做:

public delegate void MyDelegate(int a, int b, int? c = null, int? d = null);

public void Method(int a, int b, int c = 10, int d = 42) { ... }

new MyDelegate((a, b, c, d) =>
{
    if (c.HasValue && d.HasValue)
        Method(a, b, c.Value, d.Value);
    else if (c.HasValue)
        Method(a, b, c.Value);
    else if (d.HasValue)
        Method(a, b, d: d.Value);
    else
        Method(a, b);
});

但这开始变得荒谬了。

所以不,你不能轻易做你想做的事。

答案 2 :(得分:0)

Delegates / Func和方法是不同的东西。 Func不能有可选参数;这只是方法的一个特征。

作为替代方案,您可以将所有参数放入专用类ConfigFileDescriptor或其他内容,并在构造函数中使参数可选。然后,您可以使用Func<ConfigFileDescriptor, IConfigFile>。但是,由于必要的对象创建,此解决方案需要更多的输入。