C# 泛型和派生
C# Generic and Derivation
我一直在研究关于这个主题的几个帖子,但找不到以下问题的任何合适答案…
谁能告诉我为什么这不能编译:
class MyItem {
public int ID;
}
class MyList<T> {
public List<T> ItemList;
}
class MyDerivedItem : MyItem {
public string Name;
}
class MyDerivedList<MyDerivedItem> : MyList<MyDerivedItem> {
public int GetID(int index) {
return ItemList[index].ID; // ERROR : MyDerivedItem does not contain a definition for ID
}
public string GetName(int index) {
return ItemList[index].Name; // ERROR : MyDerivedItem does not contain a definition for Name
}
}
您对此有一些疑问,第一个是您的通用签名。
虽然 class MyDerivedList<MyDerivedItem> : MyList<MyDerivedItem>
看起来像是使用 MyDerivedItem
作为类型的通用 class 声明,但您实际上只是声明了一个使用 [=13] 的通用 class =] 作为泛型类型参数的名称。
您正在寻找的是 class MyDerivedList<T> : MyList<T> where T : MyDerivedItem
,它将把您的第一个问题换成您的下一个问题,即您的其他类型的属性对于这个类型来说不够可访问。
class MyItem
{
public int ID;
}
class MyList<T>
{
public List<T> ItemList;
}
class MyDerivedItem : MyItem
{
public string Name;
}
好的,现在可以从 MyDerivedList
class 访问这些属性,但还有最后一个问题需要更正。 int GetName(int index)
应该是 string GetName(int index)
,因为 Name
属性 是一个字符串。
结果如下:
class MyDerivedList<T> : MyList<T> where T : MyDerivedItem
{
int GetID(int index)
{
return ItemList[index].ID;
}
string GetName(int index)
{
return ItemList[index].Name;
}
}
哪个应该编译得很好。
Jonathon 的回答是正确的,但可能建议的解决方案并不是您想要的。
也许您只是想要一个继承封闭泛型类型的非泛型类型:
class MyDerivedList : MyList<MyDerivedItem>
现在您的代码将按预期工作:
class MyDerivedList : MyList<MyDerivedItem>
{
int GetID(int index)
{
return ItemList[index].ID;
}
string GetName(int index)
{
return ItemList[index].Name;
}
}
与您的尝试相反,在上面的代码中 MyDerivedItem
确实是类型 MyDerivedItem
而不是泛型 class MyDerivedList<>
.
令人困惑?是的,这就是为什么你应该避免用类型名称命名泛型类型参数,这会让你头疼;你的代码和下面的完全一样:
class MyDerivedList<T> : MyList<T>
但是现在 T
是泛型类型参数而不是具体类型这一事实是显而易见的。
我一直在研究关于这个主题的几个帖子,但找不到以下问题的任何合适答案…
谁能告诉我为什么这不能编译:
class MyItem {
public int ID;
}
class MyList<T> {
public List<T> ItemList;
}
class MyDerivedItem : MyItem {
public string Name;
}
class MyDerivedList<MyDerivedItem> : MyList<MyDerivedItem> {
public int GetID(int index) {
return ItemList[index].ID; // ERROR : MyDerivedItem does not contain a definition for ID
}
public string GetName(int index) {
return ItemList[index].Name; // ERROR : MyDerivedItem does not contain a definition for Name
}
}
您对此有一些疑问,第一个是您的通用签名。
虽然 class MyDerivedList<MyDerivedItem> : MyList<MyDerivedItem>
看起来像是使用 MyDerivedItem
作为类型的通用 class 声明,但您实际上只是声明了一个使用 [=13] 的通用 class =] 作为泛型类型参数的名称。
您正在寻找的是 class MyDerivedList<T> : MyList<T> where T : MyDerivedItem
,它将把您的第一个问题换成您的下一个问题,即您的其他类型的属性对于这个类型来说不够可访问。
class MyItem
{
public int ID;
}
class MyList<T>
{
public List<T> ItemList;
}
class MyDerivedItem : MyItem
{
public string Name;
}
好的,现在可以从 MyDerivedList
class 访问这些属性,但还有最后一个问题需要更正。 int GetName(int index)
应该是 string GetName(int index)
,因为 Name
属性 是一个字符串。
结果如下:
class MyDerivedList<T> : MyList<T> where T : MyDerivedItem
{
int GetID(int index)
{
return ItemList[index].ID;
}
string GetName(int index)
{
return ItemList[index].Name;
}
}
哪个应该编译得很好。
Jonathon 的回答是正确的,但可能建议的解决方案并不是您想要的。
也许您只是想要一个继承封闭泛型类型的非泛型类型:
class MyDerivedList : MyList<MyDerivedItem>
现在您的代码将按预期工作:
class MyDerivedList : MyList<MyDerivedItem>
{
int GetID(int index)
{
return ItemList[index].ID;
}
string GetName(int index)
{
return ItemList[index].Name;
}
}
与您的尝试相反,在上面的代码中 MyDerivedItem
确实是类型 MyDerivedItem
而不是泛型 class MyDerivedList<>
.
令人困惑?是的,这就是为什么你应该避免用类型名称命名泛型类型参数,这会让你头疼;你的代码和下面的完全一样:
class MyDerivedList<T> : MyList<T>
但是现在 T
是泛型类型参数而不是具体类型这一事实是显而易见的。