[英]Why doesn't c# support an object with an interface as a parameter?
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: 当我将IQueryable集合传递给ascx时,我收到此错误:
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.EdnHelpers.TagCloud(System.Web.Mvc.HtmlHelper, System.Linq.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? 我的EntityTag类不应该自动支持IQueryable吗? What am I missing?
我错过了什么? It's got to be something obvious.
它必须是明显的东西。 (I hope.)
(我希望。)
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<ITaggable>
,编译器无法“匹配”,从而产生CS1928(因为这两种类型实际上是,不同)。
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<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);
}
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. 另外,请允许我添加
IQueryable<T>
派生自IQueryable
,这意味着并非所有IQueryable
对象都是IQueryable<T>
,因此必须进行转换。 If the situation were reversed, ie 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
对象,那么将IQueryable<T>
传递给该方法肯定没有问题(因为所有IQueryable<T>
对象实际上都是IQueryable
)。
Per Craig Stuntz, a much more elegant solution using LINQ features: <%= Html.TagCloud(Model.Select(t => (ITaggable)t), 6, "entity-tags") %>
. Per Craig Stuntz,一个使用LINQ功能的更优雅的解决方案:
<%= 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. 如果您的可查询提供程序支持,您还可以使用
<%= Html.TagCloud(Model.Cast<ITaggable>(), 6, "entity-tags") %>
。
C# 4.0 will support it. C#4.0将支持它。 Search for "Covariance and Contravariance in C# 4"
搜索“C#4中的协方差和逆变”
您的EntityTag
类是IQueryable
,但编译器不知道您的标记列表实际上是EntityTag
对象的列表,它只知道它是实现ITaggable
的对象列表,可能不是IQueryable
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.