其参数扩展嵌套类的泛型类

Posted

技术标签:

【中文标题】其参数扩展嵌套类的泛型类【英文标题】:Generic class whose parameter extends a nested class 【发布时间】:2019-02-03 07:22:17 【问题描述】:

此 C# 无法编译:

public class IdList<T> where T : IdList<T>.Item 
  List<T> List = new List<T>();

  public T this[int id] 
    get => List[id];
    set  
  

  public class Item 
    public int id;
    // Not shown: id used for equality and hash.
  

编译器的抱怨是:

“IdList”类型已经包含“Item”的定义

如果我注释掉索引器,它就会编译。

我怎样才能让它编译? Rider 没有fixit。

不时尚的解决方法是不要嵌套 Item 类。

IDE 是 Rider 2018.1.4,语言级别 7.2,在 macOS 上。

【问题讨论】:

有趣的是,将内部类 Item 重命名为 Foo... 赞成教我 dotnet 的一个肮脏小秘密! 我对您的用例很感兴趣。你为什么要组织这样一个班级?也许现在还为时过早,我就无法确定您要完成的工作。但是,是的,索引器引入了一个名为“Item”的神奇属性,解决这个问题,你应该是金子 【参考方案1】:

问题在于,索引器在编译为 .NET 字节码时,会变成一个名为“Item”的属性。您需要将类型名称更改为其他名称。

【讨论】:

你可能还想看看[System.Runtime.CompilerServices.IndexerName("TheItem")] 换句话说:对错误消息稍作改进会有所帮助。【参考方案2】:

解决方案:通过使用消除名称冲突,例如, System.Runtime.CompilerServices.IndexerName("TheItem")

public class IdList<T> where T : IdList<T>.Item 
  List<T> List = new List<T>();

  [System.Runtime.CompilerServices.IndexerName("TheItem")]
  public T this[int id] 
    get => List[id];
    set  
  

  public class Item 
    public int id;
    // Not shown: id used for equality and hash.
  

编译器错误应该更明确,指出Item 已被定义为索引器的默认名称(可以被覆盖),IDE 应该提供此修复。

【讨论】:

以上是关于其参数扩展嵌套类的泛型类的主要内容,如果未能解决你的问题,请参考以下文章

Java泛型知识总结篇

Java的泛型---(英雄联盟集合嵌套案例)

java泛型——泛型类泛型方法泛型接口

泛型类的基本使用

Scala入门系列(十三):类型参数

java 定义泛型类的问题