Joh*_*ter 5 .net c# asp.net-mvc
我有以下类声明:
public class EntityTag : BaseEntity, ITaggable
Run Code Online (Sandbox Code Playgroud)
我有一个Html帮助方法:
public static string TagCloud(this HtmlHelper html, IQueryable<ITaggable> taggables,
int numberOfStyleVariations, string divId)
Run Code Online (Sandbox Code Playgroud)
这是我的ASP.NET MVC ascx:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IQueryable<EDN.MVC.Models.EntityTag>>" %>
<%@Import Namespace="EDN.MVC.Helpers" %>
<%= Html.TagCloud(Model, 6, "entity-tags") %>
Run Code Online (Sandbox Code Playgroud)
当我将IQueryable集合传递给ascx时,我收到此错误:
编译器错误消息:CS1928:'System.Web.Mvc.HtmlHelper>'不包含'TagCloud'的定义和最佳扩展方法重载'EDN.MVC.Helpers.EdnHelpers.TagCloud(System.Web.Mvc.HtmlHelper, System.Linq.IQueryable,int,string)'有一些无效的参数
如果我尝试使用以下方法显式转换对象集合:
public static string TagCloud(this HtmlHelper html, IQueryable<Object> taggables, int numberOfStyleVariations, string divId)
{
var tags = new List<ITaggable>();
foreach (var obj in taggables)
{
tags.Add(obj as ITaggable);
}
return TagCloud(html, tags.AsQueryable(), numberOfStyleVariations, divId);
}
Run Code Online (Sandbox Code Playgroud)
我得到了同样的错误 - 编译器不喜欢我传入的值.
我的EntityTag类不应该自动支持IQueryable吗?我错过了什么?它必须是明显的东西.(我希望.)
本质上,您试图将非泛型类型的对象传递IQueryable给接受泛型的方法,IQueryable<ITaggable>编译器无法"匹配"该方法,从而产生CS1928(因为这两种类型实际上是不同的).
在你的重载中接受一个IQueryable<object>(它已经在进行必要的泛型列表转换),你只需要调用泛型版本AsQueryable而不是非泛型版本,如下:
public static string TagCloud(this HtmlHelper html, IQueryable taggables, int numberOfStyleVariations, string divId)
{
var tags = new List<ITaggable>();
foreach (var obj in taggables)
{
tags.Add(obj as ITaggable);
}
return TagCloud(html, tags.AsQueryable<ITaggable>(), numberOfStyleVariations, divId);
}
Run Code Online (Sandbox Code Playgroud)
还允许我添加IQueryable<T>源自IQueryable,意味着并非所有IQueryable对象都是IQueryable<T>,从而使转换成为必要.如果情况发生逆转,即你的"真正的"辅助方法被定义为处理IQueryable对象,那么你肯定没有问题传递IQueryable<T>给该方法(因为IQueryable<T>事实上所有对象都是如此IQueryable).
Per Craig Stuntz,一个使用LINQ功能的更优雅的解决方案:
<%= Html.TagCloud(Model.Select(t => (ITaggable)t), 6, "entity-tags") %>.<%= Html.TagCloud(Model.Cast<ITaggable>(), 6, "entity-tags") %>如果您的可查询提供程序支持它,您也可以使用它.