定义将通用操作作为参数的通用操作

时间:2015-12-26 21:33:40

标签: c# lambda

我正在使用.Net 4.5。如何定义将另一个通用操作作为参数的generci操作? 当我尝试以下操作时,编译器似乎将T解释为实际类型并抱怨其定义未找到:

public static Action<Action<T>, IEnumerable<T>> RepeatForEach = (a, x) =>
        {
            foreach (T t in x)
            {
                a.Invoke(t);                
            }
        };

我尝试了以下方法,其中没有一个有效:

Action<T><Action<T>>
Action<Action<T>><T>
Action<Action<T>> where T : object

2 个答案:

答案 0 :(得分:0)

我担心C#不支持这种级别的通用性。您必须使封闭范围通用。

要么有一个班级:

public static class RepeatForEach<T>
{
    public static Action<Action<T>, IEnumerable<T>> Action = (action, enumerable)
    {
        foreach (var element in enumerable)
        {
            action.Invoke(element);
        }
    }
}

或者让方法返回动作:

public static class MyClass
{
    public static Action<Action<T>, IEnumerable<T>> GetRepeatForEachAction<T>()
    { 
        return (action, enumerable) =>
        {
            foreach (var element in enumerable)
            {
                action.Invoke(element);
            }
        }
    }
}

我还想提出一个想法foreach IEnumerable IEnumerable通常是一个非常糟糕的主意。这样做的原因是为了达到副作用,并且IEnumerable不是为此而构建的。

想象一下,通过yield return创建<button id="submitRegistration" class="btn btn-lg btn-primary btn-block" type="submit">Submit</button> 。然后你的行动可能不会影响任何元素(因为这些元素可能会被丢弃并在枚举时重新创建)。

答案 1 :(得分:0)

我认为不可能基于另一个泛型创建泛型类型。正如斯坦斯坦所说:

  

&#34;甚至需要在某处声明泛型类型。&#34;

相反,你应该尝试另一种方法,那么你创建一个扩展方法呢?这是我的消化:

Action<int> t = (int i)=> Console.WriteLine(i);
t.RepeatForEach(myitens)

所以你可以通过以下方式来调用它:

string var = File.ReadAllText("mycfg.cfg");
var = var.Replace("Hi", "Bye");
File.WriteAllText("mycfg.cfg", var);