【发布时间】:2010-03-26 05:11:57
【问题描述】:
...或者,我如何通过它们实现的接口过滤一系列类?
假设我有一个继承自 Foo 的对象序列,即seq<#Foo>。换句话说,我的序列将包含 Foo 的四个不同子类中的一个或多个。
每个子类实现不同的独立接口,与其他子类实现的接口不共享任何内容。
现在我需要将此序列过滤到仅实现特定接口的项目。
C#版本很简单:
void MergeFoosIntoList<T>(IEnumerable<Foo> allFoos, IList<T> dest)
where T : class
{
foreach (var foo in allFoos)
{
var castFoo = foo as T;
if (castFoo != null)
{
dest.Add(castFoo);
}
}
}
我可以使用 F# 中的 LINQ:
let mergeFoosIntoList (foos:seq<#Foo>) (dest:IList<'a>) =
System.Linq.Enumerable.OfType<'a>(foos)
|> Seq.iter dest.Add
但是,我觉得应该有一种更惯用的方式来完成它。我认为这会工作......
let mergeFoosIntoList (foos:seq<#Foo>) (dest:IList<'a>) =
foos
|> Seq.choose (function | :? 'a as x -> Some(x) | _ -> None)
|> Seq.iter dest.Add
但是,编译器抱怨:? 'a - 告诉我:
从类型 'b 到 'a 的运行时强制或类型测试涉及基于此程序点之前的信息的不确定类型。某些类型不允许运行时类型测试。需要进一步的类型注释。
我不知道要添加什么进一步的类型注释。接口'a 和#Foo 之间没有任何关系,只是Foo 的一个或多个子类实现了该接口。另外,可以作为'a传入的不同接口之间没有任何关系,只是它们都是由Foo的子类实现的。
一旦你们中的一个好心人指出我一直遗漏的显而易见的事情,我热切期待自己的脑袋。
【问题讨论】:
标签: f#