[英]Pass generic type parameter to 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);
我只需要創建一個關於肌腱/動作對的字典
您的字典:
Dictionary<MyEnum,Action> actions = new Dictionary<MyEnum,Action>()
{
{ValueA, ()=>{your code...}},
{ValueB, ()=>{your code...}}
};
調用方法
static void CallMyFunction(MyEnum myEnum)
{
actions[myEnum]();
}
在您的示例中,對MyFunction<>
任何調用都沒有參數 ,這意味着Action
不需要通用參數。 同樣,您不能更改為CallMyFunction<T>
因為T
取決於enum
改變。
至於<A>
, <B>
和<C>
,必須在每種case
都指定它們,而不是將其作為Action
泛型參數的一部分放入。 switch
正在調用方法,而不是GenericCall
的調用者。 這就是您要解決的關鍵點,它可以基於enum
值動態選擇<A>
, <B>
和<C>
。
試圖為myFunc
CallMyFunction
加上一個參數,實際上意味着調用者必須提供A
, B
和C
類型,這會否決switch
的目的。 我想這不是您要嘗試做的。
重構的一種方法是更改方法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
,該Attribute
采用Type
的構造函數參數,並將該Attribute
直接應用於enum
。 您可以將函數MyFunction
修改為檢查枚舉中的Attribute
,並將正確的類型正確傳遞給MyFunction
。
也就是說,僅當enum
值/類型較大(> 10)時,才值得這樣做。 目前的結構相當簡單,易於維護(如果是平凡的話)。
值得一提的是,您還可以使用反射來調用MyFunction<>
並在運行時提供泛型參數,但是您仍然可以通過enum
選擇類型。 它將添加更多代碼來維護而不是減少代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.