C# 定义将泛型操作作为参数的泛型操作
我正在使用.NET4.5。如何定义将另一个泛型操作作为参数的泛型CI操作? 当我尝试以下操作时,编译器似乎将T解释为实际类型,并抱怨找不到它的定义:C# 定义将泛型操作作为参数的泛型操作,c#,lambda,C#,Lambda,我正在使用.NET4.5。如何定义将另一个泛型操作作为参数的泛型CI操作? 当我尝试以下操作时,编译器似乎将T解释为实际类型,并抱怨找不到它的定义: public static Action<Action<T>, IEnumerable<T>> RepeatForEach = (a, x) => { foreach (T t in x) { a.Invoke(
public static Action<Action<T>, IEnumerable<T>> RepeatForEach = (a, x) =>
{
foreach (T t in x)
{
a.Invoke(t);
}
};
publicstaticactionrepeatforeach=(a,x)=>
{
foreach(T在x中)
{
a、 调用(t);
}
};
我尝试了以下方法,但均无效:
Action<T><Action<T>>
Action<Action<T>><T>
Action<Action<T>> where T : object
动作
行动
操作,其中T:object
恐怕C#不支持这种级别的泛型。您必须将封闭范围设置为通用范围
或者有一个类:
public static class RepeatForEach<T>
{
public static Action<Action<T>, IEnumerable<T>> Action = (action, enumerable)
{
foreach (var element in enumerable)
{
action.Invoke(element);
}
}
}
公共静态类RepeatForEach
{
公共静态操作Action=(操作,可枚举)
{
foreach(可枚举中的var元素)
{
调用(元素);
}
}
}
或者有一个方法返回操作:
public static class MyClass
{
public static Action<Action<T>, IEnumerable<T>> GetRepeatForEachAction<T>()
{
return (action, enumerable) =>
{
foreach (var element in enumerable)
{
action.Invoke(element);
}
}
}
}
公共静态类MyClass
{
公共静态操作GetRepeatForEachAction()
{
返回(操作,可枚举)=>
{
foreach(可枚举中的var元素)
{
调用(元素);
}
}
}
}
我还想提出一个想法,让IEnumerable
上的foreach
做一些事情通常是一个非常糟糕的主意。这样做的原因是为了产生副作用,而IEnumerable
并不是为此而设计的
想象一下,通过
收益回报
创建一个IEnumerable
。那么您的操作可能不会影响任何元素(因为这些元素可能会在枚举时被丢弃并重新创建)。我认为不可能基于另一个泛型创建泛型类型。正如sstan所说:
“即使是泛型类型也需要在某处声明。”
相反,您应该尝试另一种方法,您创建一个扩展方法怎么样?这是我的建议:
public static void RepeatForEach(this Action<T> action, IEnumerable<T> itens)
{
foreach (T t in x)
{
a.Invoke(t);
}
}
publicstaticvoidrepeatforeach(此操作,IEnumerable itens)
{
foreach(T在x中)
{
a、 调用(t);
}
}
所以你可以这样称呼它:
Action<int> t = (int i)=> Console.WriteLine(i);
t.RepeatForEach(myitens)
Action t=(inti)=>Console.WriteLine(i);
t、 RepeatForEach(myitens)
您在哪里定义什么是T
?即使是泛型类型也需要在某个地方声明,这正是我想要找到的。在问题的最后一部分,我列出了我为此所做的努力,但没有一个奏效。如何定义T?这取决于上下文。您可以在(public class ClassName{…}
)或(public void MethodName(){…}
)中声明它。@M.kazemAkhgary我不完全同意。。上面的定义与将泛型列表定义为字段有什么不同?不是。如果将列表声明为字段,则必须在作用域中定义T。关于IEnumerable
的最后一点对我来说毫无意义。什么?Eric Lippert对此有很好的解读:简言之,IEnumerable
只是可以枚举的东西,但它不会公开存储。您的操作
可能不适用于实际实体,仅适用于代理或副本,您对它们的修改可能最终会被默默地丢弃。一个包含两个IEnumerable
的示例,其中一个记住了更改,而另一个没有: