[英]Pass generic type parameter to Func
I have a couple of function like CallMyFunction
in my codebase. 我的代码库中有几个函数,例如
CallMyFunction
。 I would like to refactor them into one generic function 我想将它们重构为一个通用函数
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 be able to have something like 我希望能够有类似的东西
//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);
I would simply create a dictionary of myenum/action pairs 我只需要创建一个关于肌腱/动作对的字典
Your dictionary: 您的字典:
Dictionary<MyEnum,Action> actions = new Dictionary<MyEnum,Action>()
{
{ValueA, ()=>{your code...}},
{ValueB, ()=>{your code...}}
};
calling a method 调用方法
static void CallMyFunction(MyEnum myEnum)
{
actions[myEnum]();
}
In your example, there are no parameters for any calls to MyFunction<>
, meaning there are no generic arguments required for Action
. 在您的示例中,对
MyFunction<>
任何调用都没有参数 ,这意味着Action
不需要通用参数。 Likewise, you cannot change to CallMyFunction<T>
as T
changes depending on the enum
. 同样,您不能更改为
CallMyFunction<T>
因为T
取决于enum
改变。
As for <A>
, <B>
and <C>
, these have to be specified in each case
rather than put in as part of a generic argument to Action
. 至于
<A>
, <B>
和<C>
,必须在每种case
都指定它们,而不是将其作为Action
泛型参数的一部分放入。 The switch
is calling the methods, not the caller of GenericCall
. switch
正在调用方法,而不是GenericCall
的调用者。 It's this key point that you're working around, to dynamically select <A>
, <B>
and <C>
based on the enum
value. 这就是您要解决的关键点,它可以基于
enum
值动态选择<A>
, <B>
和<C>
。
Trying to put an argument into CallMyFunction
for myFunc
effectively means the caller has to supply the types A
, B
and C
which negates the purpose of the switch
. 试图为
myFunc
CallMyFunction
加上一个参数,实际上意味着调用者必须提供A
, B
和C
类型,这会否决switch
的目的。 This isn't what you're trying to do I think. 我想这不是您要尝试做的。
One way of refactoring would be to change the method MyFunction<T>
to take the type parameter as a parameter rather than a generic. 重构的一种方法是更改方法
MyFunction<T>
以将类型参数作为参数而不是泛型。 This would allow you to do the following; 这将允许您执行以下操作;
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);
}
However this doesn't really save you anything. 但是,这并不能真正为您节省任何费用。
To get proper value out of it, you could create a custom Attribute
that took a constructor argument of Type
and apply the Attribute
directly to the enum
. 为了从中获得适当的价值,您可以创建一个自定义
Attribute
,该Attribute
采用Type
的构造函数参数,并将该Attribute
直接应用于enum
。 Your function MyFunction
, could be modified to check for the Attribute
on the enum and correctly pass the correct type to MyFunction
. 您可以将函数
MyFunction
修改为检查枚举中的Attribute
,并将正确的类型正确传递给MyFunction
。
That said, it'd only be worth it if you had a large (>10) enum
values/types. 也就是说,仅当
enum
值/类型较大(> 10)时,才值得这样做。 The structure as it stands is fairly straight forward and easy (if mundane), to maintain. 目前的结构相当简单,易于维护(如果是平凡的话)。
It's worth mentioning that you could also use reflection to call MyFunction<>
and supply the generic argument at runtime but you'd still be left with picking out the type by enum
. 值得一提的是,您还可以使用反射来调用
MyFunction<>
并在运行时提供泛型参数,但是您仍然可以通过enum
选择类型。 It would add more code to maintain rather than reduce it. 它将添加更多代码来维护而不是减少代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.