簡體   English   中英

將通用類型參數傳遞給Func

[英]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加上一個參數,實際上意味着調用者必須提供ABC類型,這會否決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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM