Daily Knowledge Drop
A new access modifier is being introduced with C#11, the file
modifier - this will limit the accessibility of the type to the file in which it is declared.
Modifier recap
A quick recap of the existing access modifiers, along with the new file
modifier (as they relate to classes).
Existing modifiers:
private
- the class is only accessible inside the class in which it was definedpublic
- the class is accessible from everywhere in the projectprotected
- the class is accessible from within the class and all types which derive from the classinternal
- the class is accessible from within its own assembly, but not other assemblies
The new modifier:
file
- the class is accessible only from within the file in which it was defined
Example
When a class is defined, the file
modifier is applied (as opposed to public, private, etc.)
file class Class1
{
public string Name { get; set; }
}
This class now cannot be used anywhere outside the file in which is was defined. Trying to use in a different class defined in a different file, will result in a compilation error:
public class Class3
{
public Class3()
{
// NOT allowed
Class1 ca = new Class1();
}
}
The type or namespace name 'Class1' could not be found
However, as mentioned, it can be used in the same file:
// all in the same physical file
file class Class1
{
public string Name { get; set; }
}
file class Class2
{
public Class2()
{
// Totally okay
Class1 c1 = new Class1();
}
}
The file
access modifier can be applied to classes, records, structs and enums
, but cannot be used for methods or properties.
Why?
This functionality was primarily introduced to assist source generator
authors. When a source generator generates a class, its tricky to ensure it's not going to conflict with a file already in the consumer's code base. The file
modifier helps solves this by ensuring (where specified) the the source generated file is only visible where defined, and not in conflict with any developer specified class name.
Lowered code
One can use sharplab.io to see how the file
keyword is lowered:
Original code:
file class FileScopedClass { }
Lowered code:
internal class <_>FD2E2ADF7177B7A8AFDDBC12D1634CF23EA1A71020F6A1308070A16400FB68FDE__FileScopedClass { }
From this we can see that the file
keyword is translated into an internal class with a uniquely generated name
, as to not conflict with any existing name
Notes
While the intended target audience for this feature is very narrow (source generator authors), it can be leveraged by anyone if the use case calls for it. Even then, it may not get wide usage in general applications - however it is useful to know it exists and is an option if required.
References
What is the NEW "file" keyword of C# 11?
Daily Drop 189: 25-10-2022
At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.
The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.On This Page