我的代码库中有一些像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);
答案 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
的参数有效地表示调用者必须提供类型myFunc
,A
和B
,否定目的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<>
选择类型。它会添加更多代码来维护而不是减少它。