Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# HtmlHelper<;儿童类型>;不可转让给HtmlHelper<;母亲型>;_C#_.net_Generics_Oop - Fatal编程技术网

C# HtmlHelper<;儿童类型>;不可转让给HtmlHelper<;母亲型>;

C# HtmlHelper<;儿童类型>;不可转让给HtmlHelper<;母亲型>;,c#,.net,generics,oop,C#,.net,Generics,Oop,我有一个观点 ViewUserControl<SearchViewData> 在这个视图中,我引用了Html。 这是类型HtmlHelper 我创建了一个名为CommonHtmlHelper的自定义HtmlHelper类,我希望在其中执行以下操作(注意HtmlHelper参数的类型): public static SelectList translated应用程序SelectList(此HtmlHelper HtmlHelper,字符串selectedCode) 由于Search

我有一个观点

ViewUserControl<SearchViewData>
在这个视图中,我引用了Html。
这是类型
HtmlHelper

我创建了一个名为CommonHtmlHelper的自定义HtmlHelper类,我希望在其中执行以下操作(注意HtmlHelper参数的类型):

public static SelectList translated应用程序SelectList(此HtmlHelper HtmlHelper,字符串selectedCode)
由于SearchViewData继承自CommonViewData,并且我的Html类型为HtmlHelper,因此它也是HtmlHelper。
然而,当我试图访问TranslatedApplicationSelectList方法时,我在视图中看到一个错误,即HtmlHelper不可分配给HtmlHelper

这是我的OO逻辑中的一个缺陷吗?这是C#在泛型中处理继承的限制吗(我想Skeet曾经向我解释过这一点,但我再也找不到帖子了)

最重要的是,如何修复它?

.NET3.5不能处理,因此.NET3.5中唯一兼容的泛型类型是具有完全相同类型的泛型类型

一个例子说明了为什么应该允许这样做:

public class BaseType { }
public class DerivedType : BaseType { }

public void DumpList(List<BaseType> list)
{
    foreach (var o in list)
        Debug.WriteLine(o);
}

...
List<DerivedType> objects = new List<DerivedType>();
objects.Add(new DerivedType());
DumpList(objects);
公共类基类{}
公共类DerivedType:BaseType{}
公共无效转储列表(列表)
{
foreach(列表中的var o)
Debug.WriteLine(o);
}
...
列表对象=新列表();
添加(新的DerivedType());
转储列表(对象);
在这里,我们只需从对象中转储内容(即读取),这应该是安全的

一个更好的例子说明了为什么不允许这样做:

public class BaseType { }
public class DerivedType : BaseType { }

public void ManipulateList(List<BaseType> list)
{
    list.Add(new BaseType());
}

...
List<DerivedType> objects = new List<DerivedType>();
objects.Add(new DerivedType());
ManipulateList(objects);
公共类基类{}
公共类DerivedType:BaseType{}
公共无效操作列表(列表)
{
添加(新的BaseType());
}
...
列表对象=新列表();
添加(新的DerivedType());
操纵者(对象);
在这里,我们试图将
BaseType
的对象添加到已声明为存储
DerivedType
对象的列表中。这是不允许的

由于编译器无法区分这两种情况,因此它们都是不允许的,因为上面的第二种情况

在.NET4.0和C#4.0中,可以应用额外的语法,指定允许在什么方向转换泛型类型,具体取决于您打算对对象执行的操作。这可能允许两个示例中的第一个工作,但在.NET3.5中,这是不可能的。第二个示例在C#4.0中不起作用


以下是Charlie Calvert的一篇文章。

如果您的实现允许您在当前使用
HtmlHelper
的地方使用
HtmlHelper
,那么您应该能够像这样声明扩展方法:

public static SelectList TranslatedApplicationSelectList<T>(this HtmlHelper<T> htmlHelper, string selectedCode) where T : CommonViewData
public static SelectList translated application SelectList(此HtmlHelper,字符串selectedCode),其中T:commonview数据

是的,这些是约翰·斯基特早些时候向我解释的事情。我有一种感觉,这就是我问题的原因,但我不确定,也不知道术语,因此无法再次找到问题。因此,我的问题的唯一解决方案是创建一个接受HtmlHelper的方法,如果我想在另一个类型上执行该操作,则编写另一个方法:难道“强制转换”泛型类型的语法也可以接受吗?它将把责任放在程序员身上,就像常规的强制转换一样。这确实是我正在做的,但这意味着我不能在其他视图中重用该方法,因为其他子类被用作viewdata。@boris-我不确定我是否理解为什么会这样-因为扩展方法是泛型的,您可以将其用于任何子类。。。
public class BaseType { }
public class DerivedType : BaseType { }

public void ManipulateList(List<BaseType> list)
{
    list.Add(new BaseType());
}

...
List<DerivedType> objects = new List<DerivedType>();
objects.Add(new DerivedType());
ManipulateList(objects);
public static SelectList TranslatedApplicationSelectList<T>(this HtmlHelper<T> htmlHelper, string selectedCode) where T : CommonViewData