【问题标题】: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”的神奇属性,解决这个问题,你应该是金子

标签: c# inner-classes c#-7.2


【解决方案1】:

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

【讨论】:

【解决方案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 应该提供此修复。

【讨论】:

    猜你喜欢
    • 2023-01-10
    • 1970-01-01
    • 1970-01-01
    • 2019-03-10
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    相关资源
    最近更新 更多