The file keyword - C# reference (original) (raw)

Skip to main content

This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

The file modifier

In this article

Beginning with C# 11, the file contextual keyword is a type modifier.

The file modifier restricts a top-level type's visibility to the file in which it's declared. The file modifier is most often applied to types written by a source generator. File-local types provide source generators with a convenient way to avoid name collisions among generated types. The file modifier declares a file-local type, as in this example:

file class HiddenWidget
{
    // implementation
}

Any types nested within a file-local type are also only visible within the file in which it's declared. Other types in an assembly can use the same name as a file-local type. Because the file-local type is visible only in the file where it's declared, these types don't create a naming collision.

A file-local type can't be the return type or parameter type of any member declared in a non file-local type. A file-local type can't be a field member of a non-file-local. However, a more visible type can implicitly implement a file-local interface type. The type can also explicitly implement a file-local interface but explicit implementations can only be used within the same file.

The following example shows a public type that uses a file-local type to provide a worker method. In addition, the public type implements a file-local interface implicitly:

// In File1.cs:
file interface IWidget
{
    int ProvideAnswer();
}

file class HiddenWidget
{
    public int Work() => 42;
}

public class Widget : IWidget
{
    public int ProvideAnswer()
    {
        var worker = new HiddenWidget();
        return worker.Work();
    }
}

In another source file, you can declare types that have the same names as the file-local types. The file-local types aren't visible:

// In File2.cs:
// Doesn't conflict with HiddenWidget
// declared in File1.cs
public class HiddenWidget
{
    public void RunTask()
    {
        // omitted
    }
}

Member lookup prefers a file-local type declared in the same file over a non-file-local type declared in a different file. This rule ensures that a source generator can rely on member lookup resolving to a file-local type without ambiguity with other type declarations. In the preceding example, all uses of HiddenWidget in File1.cs resolve to the file-local type declared in File1.cs. The file-local declaration of HiddenWidget hides the public declaration in File2.cs.

C# language specification

For more information, see Declared accessibility in the C# Language Specification, and the C# 11 - File local types feature specification.

See also

Collaborate with us on GitHub

The source for this content can be found on GitHub, where you can also create and review issues and pull requests. For more information, see our contributor guide.

Additional resources

In this article