Skip to content

Language record

C#

C# is indexed with the member contract made explicit: an explicitly implemented interface member is recorded as an implementation, a target-typed new() resolves through the declared collection to its element type, and an event is a first-class symbol.

.cs, .csx · 1 registry id · 11 of 14 relationship types

The registry row this page is generated from

Read at render time from the same family row the register reads, so nothing in this block can disagree with it.

Extensions
.cs, .csx
Registry names
csharp
Recorded symbols
classes · interfaces · events · methods

Relationship types this analyzer constructs

11 of 14 constructed, read from this analyzer's source and re-derived by the languages gate. Each row below is one of the engine's types, in the engine's own order.

Relationship typeConstructed
callsconstructed by this analyzer
extendsconstructed by this analyzer
implementsconstructed by this analyzer
usesconstructed by this analyzer
importsconstructed by this analyzer
exportsconstructed by this analyzer
containsconstructed by this analyzer
referencesconstructed by this analyzer
overridesconstructed by this analyzer
instantiatesconstructed by this analyzer
decoratesruled absent
rendersconstructed by this analyzer
mixes_inruled absent
part_ofruled absent

11 constructed, 3 not constructed. All 3 absent types are recorded as ruled absent: the written reason and the corpus measurement behind each are in this family's completeness record. The register explains what each label means.

What this analyzer does not resolve

  • A C# base list carries no keyword distinguishing a class from an interface, so the split depends on a companion index of what each name was declared as. Without it the language rule applies: the first base extends and the rest implement.
  • Compiler-generated record members — ToString, Equals, GetHashCode, Deconstruct — and the enum ordinal are not materialized as symbols, because nobody wrote them in the file.
  • A where T : Dep constraint clause is not part of the declared-type graph, and neither is an attribute's argument types; both are real dependency positions left unwritten rather than approximated.

Every line above was written against C#’s own analyzer module and is named against a construct in it, so it can be checked against the source. Nothing here is inherited from a template, or from another language’s page.

Where you meet it in a repository

Recognised by extension — .cs, .csx. Everything below is about where those files actually sit in a working repository.

  • WinForms and WPF split one class across a designer file and a hand-written file with partial, so a form's members live in two places.
  • An async method returns a task; awaiting a call does not change which symbol the call edge points at.
  • Interfaces are declared in one project and implemented in several, so the contract and the implementation are rarely in the same file.

Questions this index answers

Phrased as retrievals, because that is what an index can honestly do: it holds the symbols and the edges between them, and hands them back with the evidence attached.

  1. Which class members implement this interface member?
  2. Which types implement this interface?
  3. Where is this event declared, and which type declares it?
  4. What does this override replace?

What the analyzer sees in code like this

A class, its interface, a target-typed new and an explicit member
namespace Acme;

public class Widgets : IThing {        // bb records: class Widgets · implements IThing
    private List<Widget> _items = new();   // bb records: instantiates Widget

    public override string ToString() => nameof(Widget);

    void IThing.Explicit() { }          // bb records: an implementation of IThing.Explicit
}

Symbols are stored with the file they came from and the bytes they span, so a hit points at a line rather than at a guess. The annotations in the sample are commentary for the reader, not strings the index would store.

Languages that turn up in the same repository

Application & systems — the count beside each name is how many relationship types that family’s analyzer constructs.

The extensions, registry names, recorded symbols and relationship types above are the parser registry row for C#, read while the page rendered — the same row the register reads, so the two surfaces cannot tell two stories. Every relationship type listed as constructed appears in src/ast/real-*, the analyzer modules bb ships. bb 0.1.0 answers from a local store over 50 languages (53 registry ids, three of them aliases). There is no benchmark on this page: every claim here is one you can go and read in the source.