Skip to main content
.NET Tips

Do You Know About The File Access Modifier In C#?

The file access modifier in C# is like keeping your tools in the right drawer—everything stays organized, and nothing gets mixed up where it doesn’t belong!

Christian Schou Køster

In C# 11, a new access modifier called file was introduced. It restricts the accessibility of types and members to the containing file, offering a lightweight alternative to internal or private. 🤘

This is especially useful for helper classes or methods you want to limit to a single file, ensuring cleaner code organization and better encapsulation. 🔥

A Quick Demonstration 🧑‍💻

Below is a simple example on how to use the file access modifier in C#.

file class HelperClass
{
    public static string GetMessage()
    {
        return "This is a file-scoped class.";
    }
}

public class MyClass
{
    public string DisplayMessage()
    {
        return HelperClass.GetMessage();
    }
}

What is going on above? Let me explain 😄

The HelperClass is restricted to the file MyHelper.cs because of the file access modifier. It can only be used within this file, ensuring it’s not accessible anywhere else in the project.

This keeps HelperClass isolated, allowing you to organize utility or helper functionality without exposing it to other parts of your application. Awesome right?! 👌

Still Not Getting It? 😅

I totally understand! Let me try with another example. Imagine you have two files with helper classes that could potentially conflict if they were accessible across the entire project.

Without file Modifier

Image you got a file named Utilities1.cs.

internal class Logger
{
    public static void Log(string message)
    {
        Console.WriteLine($"Utilities1 Log: {message}");
    }
}

public class MyClass1
{
    public void DoWork()
    {
        Logger.Log("Doing work in MyClass1.");
    }
}

And another named Utilities2.cs.

internal class Logger
{
    public static void Log(string message)
    {
        Console.WriteLine($"Utilities2 Log: {message}");
    }
}

public class MyClass2
{
    public void DoWork()
    {
        Logger.Log("Doing work in MyClass2.");
    }
}

What could possible end up bad here? Well... both Logger classes are internal. If someone from another file in the same project tries to use Logger, there will be confusion or conflicts since both files have a Logger class. You might even accidentally reference the wrong one. 😬

So how can we solve that?

With file Modifier

Let's update our Utilities to use the file access modifier instead of internal.

First file named Utilities1.cs goes here.

file class Logger
{
    public static void Log(string message)
    {
        Console.WriteLine($"Utilities1 Log: {message}");
    }
}

public class MyClass1
{
    public void DoWork()
    {
        Logger.Log("Doing work in MyClass1.");
    }
}

And the second one named Utilities2.cs is here.

file class Logger
{
    public static void Log(string message)
    {
        Console.WriteLine($"Utilities2 Log: {message}");
    }
}

public class MyClass2
{
    public void DoWork()
    {
        Logger.Log("Doing work in MyClass2.");
    }
}

Why This Is a Good Idea? 🤨

  • No Naming Conflicts! Each file has its own Logger class, but they can't conflict because their scope is limited to the file. Both Logger classes can coexist even though they have the same name, and neither will accidentally be accessed from other files.
  • Cleaner Encapsulation. You ensure that Logger in Utilities1.cs and Utilities2.cs only impacts the respective file. If you don't need the Logger class outside these files, file helps prevent accidental exposure of them.

This approach helps with modularity, avoids naming clashes, and keeps the scope of helper classes or utility methods limited to where they're needed.

An Analogy To Understand It

Imagine you're working on two different school projects at the same time, and each project has its own helper friend named "Alex." But the problem is, if both projects are in the same room, you might get confused about which "Alex" to ask for help!

Now, the file access modifier is like keeping each "Alex" in their own room (one for each project). So, when you're working on Project 1, you only see and talk to Alex from Project 1, and when you’re working on Project 2, you only see Alex from Project 2.

This way, there’s no confusion or mix-up, and you can work on both projects without accidentally calling the wrong "Alex". Genius right? 🙌

Resources

You can read more about the file keyword from the official Microsoft documentation below.

file keyword - C# reference
file modifier: Declare types whose scope is the file in which it’s declared
Christian Schou Køster