将泛型类型参数传递给Func

时间:2017-11-01 19:12:44

标签: c# generics func

我的代码库中有一些像CallMyFunction这样的函数。我想将它们重构为一个通用函数

enum MyEnum
{
    ValueA,
    ValueB,
    ValueC
}

static void MyFunction<T>()
{
    //...
}

static void CallMyFunction(MyEnum myEnum)
{
    switch (myEnum)
    {
        case MyEnum.ValueA:
            MyFunction<A>();
            break;
        case MyEnum.ValueB:
            MyFunction<B>();
            break;
        case MyEnum.ValueC:
            MyFunction<C>();
            break;                                                              
    }
}

我希望能够拥有像

这样的东西
//I would like to make it work for Func<T> too
static void GenericCall(MyEnum myEnum, Action<?????> myFunc) 
{
    switch (myEnum)
    {
        case MyEnum.ValueA:
            myFunc<A>();
            break;
        case MyEnum.ValueB:
            myFunc<B>();
            break;
        case MyEnum.ValueC:
            myFunc<C>();
            break;                                                              
    }
}

//And then call it like this
GenericCall(myEnum, MyFunction);
GenericCall(myEnum, AnotherFunction);

2 个答案:

答案 0 :(得分:2)

我只想创建一个 myenum / action 对的字典

你的词典:

Dictionary<MyEnum,Action> actions = new Dictionary<MyEnum,Action>()
{
    {ValueA, ()=>{your code...}},
    {ValueB, ()=>{your code...}}
};

调用方法

static void CallMyFunction(MyEnum myEnum)
{
    actions[myEnum]();
}

答案 1 :(得分:0)

在您的示例中,对MyFunction<>的任何调用都没有参数,这意味着Action不需要通用参数。同样,根据CallMyFunction<T>,您无法更改为T enum更改。

至于<A><B><C>,必须在每个case中指定这些内容,而不是作为{{1}的通用参数的一部分放入}。 Action正在调用方法,而不是switch的调用者。这是您正在解决的关键点,要根据GenericCall值动态选择<A><B><C>

尝试将enum CallMyFunction的参数有效地表示调用者必须提供类型myFuncAB,否定目的C的。{这不是你想要做的事情。

重构的一种方法是更改​​方法switch以将type参数作为参数而不是泛型。这将允许您执行以下操作;

MyFunction<T>

然而,这并没有真正为你节省任何东西。

要从中获取正确的价值,您可以创建一个自定义enum MyEnum { ValueA, ValueB, ValueC } static void MyFunction(Type type) { //... } static void CallMyFunction(MyEnum myEnum) { Type type; switch (myEnum) { case MyEnum.ValueA: type = typeof(A); break; case MyEnum.ValueB: type = typeof(B); break; case MyEnum.ValueC: type = typeof(C); break; } MyFunction(type); } ,其中包含Attribute的构造函数参数,并将Type直接应用于Attribute。您的函数enum可以修改为检查枚举上的MyFunction并正确地将正确的类型传递给Attribute

那就是说,如果你有一个大的(> 10)MyFunction值/类型,那就值得了。现在的结构是相当直接的,很容易(如果平凡的话),维持。

值得一提的是,您还可以使用反射来调用enum并在运行时提供泛型参数,但仍然需要通过MyFunction<>选择类型。它会添加更多代码来维护而不是减少它。