我在C#中使用自定义扩展方法:
IF([formula]=0,"",1)
正如您可能猜到的,这种方法是一个稍微调整过的版本:
//version 1
public static IEnumerable<TSource> ForEachAndReturnSelf<TSource>(this IEnumerable<TSource> container, System.Action<TSource> delegateAction)
{
foreach (var v in container) delegateAction(v); return container;
}
唯一不同的是我的方法返回自己(不是void):
无论如何,该方法的版本工作正常
但我有这个方法的新版本返回原始类型而不是System.Collections.Generic.List<T>.ForEach()
所以我把方法改为:
IEnumerable<TSource>
因为我需要像这样使用它:
//version 2
public static T ForEachAndReturnSelf<T,TSource>(this T container, System.Action<TSource> delegateAction) where T : IEnumerable<TSource>
{
foreach (var v in container) delegateAction(v); return container;
}
但是当我将版本1更改为2时,使用此方法的代码的所有部分现在都会产生编译器错误:
方法的类型参数 无法从使用情况中推断出
//Example Usage1 List<int> list = /* initialize */; list.ForEachAndReturnSelf(_ => _ *= 2).Convert(_ => _.ToString()).Sort(); //Example Usage2 list.ForEachAndReturnSelf(_ => _ *= 2)[0] = 4;
。尝试 明确指定类型参数
问题是:
我认为提供的类型信息足以推断出类型,但为什么不能呢?
我如何满足提供类型知识,以便我可以返回与提供的原始类型相同的类型?
答案 0 :(得分:2)
首先,你的方法签名只有一个通用参数需要两个,所以看起来应该是这样的
public static TCollection ForEachAndReturn<TCollection,TItem>(this TCollection Container, Action<TItem> action)
where TCollection : IEnumerable<TItem>
{
foreach (var item in Container)
{
action(item);
}
return Container;
}
现在您仍然会收到您提到的编译器警告。这是因为可以推断您的收藏类型。但是,你是通用约束,说TCollection必须是IEnumberable<TSource>
类型,只能用于提供有关TCollection的信息。这就是为什么你需要告诉编译器TSource的类型。通用约束就是这样,它们用于约束,你不能从你正在约束的东西推断约束的类型,我想这可能会导致问题。因此,为什么无法从TCollection提供的泛型参数推断出TSource。
我希望这是有道理的。
编辑:错过了一点对不起,所以要摆脱编译器警告,你得到的只是需要提供类型信息。var myList = new List<string>();
list.ForEachAndReturn<List<string>,string>(i => //do stuff);
答案 1 :(得分:0)
因此,首先,您只需要一个通用参数,而您需要其中的两个。将您的方法定义更改为:
public static TCollection ForEachAndReturnSelf<TCollection, TItem>(this TCollection container, System.Action<TItem> delegateAction) where TCollection : IEnumerable<TItem>
现在要使用它,您必须包含您用来调用此方法的泛型类型:
meList.ForEachAndReturnSelf<List<int>, int>(i => ... );