【发布时间】:2012-12-23 03:45:38
【问题描述】:
我发誓这没有意义。
鉴于我有来自 Web API 的 HttpRouteCollection,我正在根据一些自定义路由类型进行过滤,特别是 IAttributeRoute。我使用httpRoutes.OfType<IAttributeRoute>(),但循环的行为就像没有元素一样。
需要明确的是,当这个循环被命中时,整个集合都是HttpAttributeRoute 类型,它直接实现IAttributeRoute。此外,我在常规 RouteCollection 上运行 same 循环。
这不起作用:
foreach (IAttributeRoute route in GlobalConfiguration.Configuration.Routes.OfType<IAttributeRoute>()) {
if (!string.IsNullOrWhiteSpace(route.RouteName) && !json.ContainsKey(route.RouteName)) {
json.Add(route.RouteName, "/" + route.Url);
}
}
不过,这很好用:
foreach (var route in GlobalConfiguration.Configuration.Routes)
{
if (route is IAttributeRoute) // uhhhh?
{
var r = route as IAttributeRoute;
if (!string.IsNullOrWhiteSpace(r.RouteName) && !json.ContainsKey(r.RouteName))
{
json.Add(r.RouteName, "/" + r.Url);
}
}
}
我发誓我没有说谎,它只适用于后面的代码。就像我说的,在正常的路由集合上执行此操作很好。正常的路由集合有其他类型,不仅仅是IAttributeRoute,而且HttpRouteCollection只有有IAttributeRoute,在它的当前状态下(将来它可能有不同类型的路由)。这可能是一个因素吗?
我是否遗漏了什么,或者OfType 没有做我在内部做的事情?
【问题讨论】:
-
嗯,很有趣。
OfType应该执行一次转换并且如果转换失败不会抛出(即它的工作方式类似于as运算符)。您可能只需要在 linq 查询中添加.Where( r => r != null )。 -
OfType执行foreach循环,在满足上述条件的情况下进行is比较,然后是yield return。 -
你能给我们一些重现这种行为的代码,以便我们解决它吗?有些事情我想尝试一下,看看会发生什么:
Routes.Cast<IAttributeRoute>()和Routes.AsEnumerable().OfType<IAttributeRoute>() -
当然,我可以尝试制作一个样本。 Cast 可能现在可以工作,因为每条路线都是一个属性路线,但可能不是面向未来的。我也会试试
AsEnumerable。 -
我的猜测是一个版本使用
IEnumerable.GetEnumerator和另一个IEnumerable<T>.GetEnumerator沿线某处过载。
标签: c# linq linq-to-objects