【发布时间】:2016-07-17 12:50:35
【问题描述】:
我正在实现一个流畅的参数断言库,其中的重点是编译时的强类型检查。 Intellisense 应该只显示可用于断言类型的方法和扩展。
在为 IEnumerable 创建扩展时,我在解析正确的类型参数时遇到问题。
库中的想法是,您可以在任何类型上调用 ThrowIf(或 ThrowIfNot),这将返回 IAssertion 类型的断言实例:
public static IAssertion<T> ThrowIf<T>(this T t)
{
return new IfAssertion<T>(t);
}
现在我想检查 IEnumerable 是否包含特定项目。将有两个重载,一个将 T 类型的对象作为参数,另一个将一个函数用于执行评估:
public static T1 Contains<T1, T2>(this IAssertion<T1> assertion, T2 item)
where T1 : IEnumerable<T2>
{
// assertion logic
return assertion.Value;
}
public static T1 Contains<T1, T2>(this IAssertion<T1> assertion, Func<T2, bool> func)
where T1 : IEnumerable<T2>
{
// assertion logic
return assertion.Value;
}
使用重载获取实际类型的实例时一切正常。但是后一种使用函数编译器无法正确推断类型参数,除非进行强制转换:
var list = new List<string>();
list.ThrowIf().Contains("foo"); // compiles
list.ThrowIf().Contains((string s) => false); // compiles
list.ThrowIf().Contains(s => false); // does not compile
有没有什么方法可以让编译器满意而无需对函数参数进行强制转换?
更多实现细节可以从这里找到: https://bitbucket.org/mikalkai/argument-assertions/overview
【问题讨论】:
-
我觉得你只能做
Contains<string>(s => false) -
不。您需要将其命名为 Contains
, string>(s => false)。
标签: c# interface extension-methods func inferred-type