I have the following class declaration:
我有以下班级声明:
public class EntityTag : BaseEntity, ITaggable
I have an Html helper method:
我有一个Html助手方法:
public static string TagCloud(this HtmlHelper html, IQueryable<ITaggable> taggables,
int numberOfStyleVariations, string divId)
This is my ASP.NET MVC ascx:
这是我的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") %>
When I pass in an IQueryable collection to the ascx, I get this error:
当我向ascx传递一个IQueryable集合时,我得到以下错误:
Compiler Error Message: CS1928: 'System.Web.Mvc.HtmlHelper>' does not contain a definition for 'TagCloud' and the best extension method overload 'EDN.MVC.Helpers.EdnHelpers.TagCloud(System.Web.Mvc.HtmlHelper, System.Linq.IQueryable, int, string)' has some invalid arguments
编译错误信息:CS1928: 'System.Web.Mvc。HtmlHelper>'不包含'TagCloud'的定义和最好的扩展方法重载' edn . mvc . helpers.tagcloud (System.Web.Mvc)。HtmlHelper来。IQueryable, int, string)'有一些无效的参数
If I try to explicitly convert the object collection with this:
如果我试图显式地将对象集合转换为:
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);
}
I get the same error - the values I'm passing in are not liked by the compiler.
我得到了相同的错误——我传递的值不被编译器喜欢。
Shouldn't my EntityTag class automatically be supported as IQueryable? What am I missing? It's got to be something obvious. (I hope.)
难道我的EntityTag类不应该被自动支持为IQueryable吗?我缺少什么?一定是显而易见的。(我希望)。
3 个解决方案
#1
5
Essentially, you're trying to pass an object of the non-generic type IQueryable
to a method that accepts the generic IQueryable<ITaggable>
, which the compiler cannot "match", resulting in the CS1928 (since the two types are, in fact, different).
本质上,您试图将非泛型IQueryable类型的对象传递给接受泛型IQueryable
In your overload that accepts an IQueryable<object>
(which is already doing the necessary conversion to a generic list), you simply need to call the generic version of AsQueryable
instead of the non-generic one, as such:
在接受IQueryable
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);
}
Allow me to add, as well, that IQueryable<T>
derives from IQueryable
, meaning that not all IQueryable
objects are IQueryable<T>
, thus making the conversion necessary. If the situation were reversed, i.e. your "real" helper method was defined to handle IQueryable
objects, then you certainly would have no problem passing an IQueryable<T>
to that method (since all IQueryable<T>
objects are, in fact, IQueryable
).
请允许我补充一点,IQueryable
Per Craig Stuntz, a much more elegant solution using LINQ features: <%= Html.TagCloud(Model.Select(t => (ITaggable)t), 6, "entity-tags") %>
. You can also use <%= Html.TagCloud(Model.Cast<ITaggable>(), 6, "entity-tags") %>
if your queryable provider supports it.
根据Craig Stuntz,使用LINQ特性的更优雅的解决方案:<%= Html.TagCloud(Model)。选择(t => (itagable)t), 6,“实体标签”)%>。如果可查询提供者支持,还可以使用<%= Html.TagCloud(Model.Cast
#2
2
C# 4.0 will support it. Search for "Covariance and Contravariance in C# 4"
c# 4.0将支持它。搜索“c# 4中的协方差和逆变”
#3
1
Your EntityTag
class is IQueryable
, however the compiler doesn't know that your list of tags is actually a list of EntityTag
objects, it only knows that it's a list of objects implementing ITaggable
, which probably isn't IQueryable
.
你的EntityTag类是IQueryable,但是编译器不知道你的标签列表实际上是EntityTag对象的列表,它只知道它是实现ITaggable的对象列表,这可能不是IQueryable。
#1
5
Essentially, you're trying to pass an object of the non-generic type IQueryable
to a method that accepts the generic IQueryable<ITaggable>
, which the compiler cannot "match", resulting in the CS1928 (since the two types are, in fact, different).
本质上,您试图将非泛型IQueryable类型的对象传递给接受泛型IQueryable
In your overload that accepts an IQueryable<object>
(which is already doing the necessary conversion to a generic list), you simply need to call the generic version of AsQueryable
instead of the non-generic one, as such:
在接受IQueryable
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);
}
Allow me to add, as well, that IQueryable<T>
derives from IQueryable
, meaning that not all IQueryable
objects are IQueryable<T>
, thus making the conversion necessary. If the situation were reversed, i.e. your "real" helper method was defined to handle IQueryable
objects, then you certainly would have no problem passing an IQueryable<T>
to that method (since all IQueryable<T>
objects are, in fact, IQueryable
).
请允许我补充一点,IQueryable
Per Craig Stuntz, a much more elegant solution using LINQ features: <%= Html.TagCloud(Model.Select(t => (ITaggable)t), 6, "entity-tags") %>
. You can also use <%= Html.TagCloud(Model.Cast<ITaggable>(), 6, "entity-tags") %>
if your queryable provider supports it.
根据Craig Stuntz,使用LINQ特性的更优雅的解决方案:<%= Html.TagCloud(Model)。选择(t => (itagable)t), 6,“实体标签”)%>。如果可查询提供者支持,还可以使用<%= Html.TagCloud(Model.Cast
#2
2
C# 4.0 will support it. Search for "Covariance and Contravariance in C# 4"
c# 4.0将支持它。搜索“c# 4中的协方差和逆变”
#3
1
Your EntityTag
class is IQueryable
, however the compiler doesn't know that your list of tags is actually a list of EntityTag
objects, it only knows that it's a list of objects implementing ITaggable
, which probably isn't IQueryable
.
你的EntityTag类是IQueryable,但是编译器不知道你的标签列表实际上是EntityTag对象的列表,它只知道它是实现ITaggable的对象列表,这可能不是IQueryable。