File-scoped types

file är en åtkomstmodifierare som begränsar en typ till filen den definieras i — osynlig för all annan kod i projektet. Inte ens internal är lika begränsad.

När du läst detta ska du kunna

  • Deklarera en file-scoped klass, struct eller record
  • Förklara varför file är snävare än internal
  • Välja när file är rätt val framför private nested types

Åtkomst-hierarkin i C#

public → alla som kan se assemblyt
internal → bara inom samma assembly (projekt)
protected → klassen och dess subklasser
private → bara klassen/struct:en
file → bara den här .cs-filen ← C# 11

file är ännu snävare än internal — två klasser i samma assembly men i olika filer ser inte varandras file-typer.

Grundläggande syntax

Helpers.cs
file class JsonHelper
{
public static string Serialize(object obj)
=> System.Text.Json.JsonSerializer.Serialize(obj);
}
file record TempResult(bool Success, string Message);
// Bara synlig här i Helpers.cs

Utanför Helpers.cs finns varken JsonHelper eller TempResult — kompilatorn ser dem inte.

Praktiskt — isolera hjälpklasser

OrderService.cs
public class OrderService
{
public OrderDto GetOrder(int id)
{
var raw = Database.Query<RawOrder>(id);
return Mapper.ToDto(raw); // privat hjälpklass
}
}
// Dessa typer behövs bara här — ingen ska se dem utifrån
file static class Mapper
{
public static OrderDto ToDto(RawOrder raw) => new(raw.Id, raw.CustomerName, raw.Total);
}
file record RawOrder(int Id, string CustomerName, decimal Total, string InternalCode);
file record OrderDto(int Id, string CustomerName, decimal Total);

Mapper och RawOrder är internt stödstrukturer. Med file säger du explicit att de hör till just den här filen — och ingenting mer.

Source generators använder file

Roslyn-källgeneratorer genererar kod i separata filer. file-typer är perfekta för hjälpkod som genereras, eftersom de aldrig krockar med namnen i din handskrivna kod — även om de råkar heta likadant.

// AutoGenerated.g.cs (genererad fil)
file static class SerializerHelper // krockar inte med din egen SerializerHelper
{
// ...
}

Skillnad mot private nested class

// Gammal lösning — nested private class
public class OrderService
{
private class Mapper { ... } // synlig bara inom OrderService
}
// C# 11 — file class
file class Mapper { ... } // synlig bara i den här filen, utanför klassen

file är lösningen när hjälpklassen används av flera klasser i samma fil men inte ska synas utanför den.

Begränsningar

  • file kan kombineras med static, abstract, sealed men inte med public, internal, protected eller private
  • Interfaces och enum kan också vara file-scoped
  • Gäller bara top-level types — inte nested types

TL;DR

// I CustomerProcessor.cs
file record ParsedCustomer(string Name, string Email, bool IsValid);
file static class CustomerValidator
{
public static ParsedCustomer Parse(string input)
{
// ...
return new ParsedCustomer(name, email, valid);
}
}
// I andra filer i samma projekt: ParsedCustomer och CustomerValidator existerar inte

Använd file för hjälptyper som bara används i en fil. Det håller namespaces rena och gör det tydligt att typen inte är tänkt att återanvändas.