我有以下类声明:
public class EntityTag : BaseEntity, ITaggable
我有一个Html帮助方法:
public static string TagCloud(this HtmlHelper html, IQueryable<ITaggable> taggables,
int numberOfStyleVariations, string divId)
这是我的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") %>
当我将IQueryable集合传递给ascx时,我收到此错误:
编译器错误消息:CS1928:'System.Web.Mvc.HtmlHelper&gt;'不包含'TagCloud'的定义和最佳扩展方法重载'EDN.MVC.Helpers.EdnHelpers.TagCloud(System.Web.Mvc.HtmlHelper,System.Linq.IQueryable,int,string)'有一些无效的参数< / p>
如果我尝试使用以下方法显式转换对象集合:
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);
}
我得到了同样的错误 - 编译器不喜欢我传入的值。
我的EntityTag类不应该自动支持IQueryable吗?我错过了什么?它必须是明显的东西。 (我希望。)
答案 0 :(得分:5)
基本上,您尝试将非泛型类型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);
}
同样请允许我添加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") %>
。
答案 1 :(得分:2)
C#4.0将支持它。 搜索“C#4中的协方差和逆变”
答案 2 :(得分:1)
您的EntityTag
类是IQueryable
,但是编译器不知道您的标记列表实际上是EntityTag
个对象的列表,它只知道它是一个对象列表实施ITaggable
,可能不是IQueryable
。