简体   繁体   中英

Generic class whose parameter extends a nested class

This C# doesn't compile:

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.
  }
}

The complaint from the compiler is:

The type 'IdList' already contains a definition for 'Item'

If I comment out the indexer, it compiles.

How can I get this to compile? Rider doesn't have a fixit.

The unstylish workaround is not to nest the Item class.

IDE is Rider 2018.1.4, Language level 7.2, on macOS.

The issue is that the indexer, when compiled to .NET byte code, becomes a property called "Item". You need to change your type name to something else.

Solution: eliminate the name collision by using, for example, 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.
  }
}

The compiler error should be more explicit and say that Item is already defined as the default name (which can be overridden) for the indexer, and the IDE should offer this fixit.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM