C# 将泛型类型参数传递给Func
我的代码库中有两个函数,比如C# 将泛型类型参数传递给Func,c#,generics,func,C#,Generics,Func,我的代码库中有两个函数,比如CallMyFunction。我想把它们重构成一个通用函数 enum MyEnum { ValueA, ValueB, ValueC } static void MyFunction<T>() { //... } static void CallMyFunction(MyEnum myEnum) { switch (myEnum) { case MyEnum.ValueA:
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;
}
}
enum MyEnum
{
瓦卢亚,
瓦卢布,
瓦卢克
}
静态函数()
{
//...
}
静态void CallMyFunction(MyEnum MyEnum)
{
开关(myEnum)
{
案例MyEnum.ValueA:
MyFunction();
打破
案例MyEnum.ValueB:
MyFunction();
打破
案例MyEnum.ValueC:
MyFunction();
打破
}
}
我希望能有这样的东西
//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);
//我想让它也为Func工作
静态void GenericCall(MyEnum MyEnum,Action myFunc)
{
开关(myEnum)
{
案例MyEnum.ValueA:
myFunc();
打破
案例MyEnum.ValueB:
myFunc();
打破
案例MyEnum.ValueC:
myFunc();
打破
}
}
//然后像这样称呼它
GenericCall(myEnum,MyFunction);
GenericCall(myEnum,另一个函数);
在您的示例中,对MyFunction
的任何调用都没有参数,这意味着操作
不需要通用参数。同样,您不能更改为CallMyFunction
,因为T
的更改取决于enum
对于
、
和
,必须在每个案例中指定它们,而不是作为操作的通用参数的一部分。开关
正在调用方法,而不是GenericCall的调用方
。这是您正在解决的关键点,根据枚举
值动态选择
、
和
尝试将参数放入myFunc
的CallMyFunction
中实际上意味着调用者必须提供类型A
、B
和C
,这否定了开关的用途。我想这不是你想做的
重构的一种方法是将方法MyFunction
更改为将类型参数作为参数而不是泛型参数。这将允许您执行以下操作:
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);
}
然而,这并不能真正为你节省任何东西
为了从中获得适当的值,您可以创建一个自定义的属性
,该属性采用类型
的构造函数参数,并将属性
直接应用于枚举
。可以修改函数MyFunction
,以检查枚举上的属性
,并将正确的类型正确传递给MyFunction
也就是说,只有当您有一个大(>10)enum
value/type时,才值得这么做。目前的结构相当简单,易于维护(如果很普通的话)
值得一提的是,您还可以使用反射来调用MyFunction
,并在运行时提供泛型参数,但仍然需要通过enum
来选择类型。它将添加更多代码来维护,而不是减少代码。我只需创建一个myenum/action对字典
你的字典:
Dictionary<MyEnum,Action> actions = new Dictionary<MyEnum,Action>()
{
{ValueA, ()=>{your code...}},
{ValueB, ()=>{your code...}}
};
根据以下内容:,这可能会影响性能。@KOTIX我同意如果您有数百万个交换机案例。@KOTIX,您也会有lambda的性能开销。如果您对性能开销还满意的话,这是一种相当干净的方法。@DiskJunky lamda查询只是编译时确定的函数调用。不是什么大话题x=>x==1
仅等于delegate(inti){return x==1;}
@Bruno问题是你的,使用与否,但你之前评论中的所有参数都是无效的(关于安全性、代码重复等。我认为你对这个答案理解不够)
static void CallMyFunction(MyEnum myEnum)
{
actions[myEnum]();
}