

C# 11 File Scoped Types
source link: https://blog.ndepend.com/c-11-file-scoped-types/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

C# 11 File Scoped Types
C#11 added the file scoped types feature: a new file
modifier that can be applied to any type definition to restrict its usage to the current file. This way we can have several classes with the same name (namespace.name
) in a single project. This is shown through the project below that contains two classes named ConsoleApp1.Answer
:
Here are a few remarks:
- The types with the
file
modifier can be indirectly accessed outside of their source file. In the program above we rely on theinternal
classesInternalClassFromFile1
andInternalClassFromFile2
to run bothAnswer
classes fromProgram
. - Such
file
class can also be indirectly used outside its source file through an interface this way:
namespace ConsoleApp1 { file class Answer : IAnswer { public string GetFileScopeSecret() => "Answer from File1.cs"; internal interface IAnswer { string GetFileScopeSecret(); static class InternalClassFromFile1 { internal static IAnswer GetAnswer() => new Answer(); |
- Any kind of type can be marked with the
file
modifier:class
, interface, record,struct
,enum
,delegate
. file
cannot be used with another modifier likeinternal
orpublic
.- file partial can be used as long as all the type definitions belong to the same file:
namespace ConsoleApp1 { file static partial class Answer { internal static string GetFileScopeSecret() => "Answer from File1.cs"; file static partial class Answer { internal static string AnotherGetFileScopeSecret() => "Another Answer from File1.cs"; |
- The
file
modifier doesn’t apply to types nested in a parent type. Also it doesn’t apply to methods properties, events and fields but the language design note explains: “Leaves the design space open for non-type file-scoped members to come along later.” - As the screenshot below shows, it is possible to have in a project, a single
internal
orpublic
class with full nameConsoleApp1.Answer
, and one or severalfile ConsoleApp1.Answer
. The only drawback is that the public class cannot be used within source files containing a file scoped class.
Why this feature?
Let’s underline that namespace
remains the preferred way to avoid type name collision. However we can imagine several use cases for this feature:
- Generated code: Typically generated templates often use the same class name again and again, like
Item
,Info
orDataSet
. To prevent collision we had to either nest anItem
class in a parent class or maintain an index in name for each generated version, likeItem1
,Item2
… Thus the keywordfile
can significantly ease code generation. - Extension method: Extension method is nowadays a popular language construct for C# developers. However there can be extension method naming collision. With this
file
visibility restriction it is now easy to have extension methods restricted to a single file. Another common issue with extension method -solved by thisfile
visibility restriction- is that they pollute intellisense dropdowns. - Nested class: To solve the naming collision within a project, a common solution mentioned above is that we used to declare private nested classes. However this is not clean code because an extra indentation level is added, and too much indentation clutters code. Thus the
file
keyword will help with this concern. - Module and Encapsulation: Typically what you consider as a module or a component is not a single class but a few highly cohesive types. For encapsulation purposes a pattern was to nest private implementation details within private nested classes and types. This
file
scope makes such encapsulation pattern cleaner. - Test: Often tests structure is standardized and each test class has its own
DataSet
class for example. Here also instead of declaring classes nested in test classes, thefile
restriction will help.
However keep in mind that a file
restricted class won’t be visible from tests. Those must be considered as private implementation (black box) and must be tested through internal
or public
classes that access them.
Quick tip: You can test your internal
implementations by tagging your projects with the System.Runtime.CompilerServices.InternalsVisibleToAttribute
. This way you don’t have to declare these classes as public just for testing purposes.
[assembly: InternalsVisibleTo("NDepend.Test.Unit, PublicKey=002400000480...")] |
What the compiler generates?
The C# compiler renames types with the file restriction this way: <SourceFileNameWithoutExtension>F$index$_TypeName. The index is incremented to avoid collision when a project has several source files with the same name containing file scoped types.
Thanks to the <> characters there is no risk for such class to be consumed from elsewhere than its file. This common compiler renaming pattern is called special naming and is used in a number of scenario including async/await , lambda, anonymous method, anonymous type.
Interestingly enough, when analyzing a bunch of projects within a solution, NDepend doesn’t try to change special names. Thus the NDepend dependency graph of the small program shown in the first screenshot above looks like this:
Again another great C# featurette that will help us write even cleaner code :))
My dad being an early programmer in the 70's, I have been fortunate to switch from playing with Lego, to program my own micro-games, when I was still a kid. Since then I never stop programming.
I graduated in Mathematics and Software engineering. After a decade of C++ programming and consultancy, I got interested in the brand new .NET platform in 2002. I had the chance to write the best-seller book (in French) on .NET and C#, published by O'Reilly and also did manage some academic and professional courses on the platform and C#.
Over my consulting years I built an expertise about the architecture, the evolution and the maintenance challenges of large & complex real-world applications. It seemed like the spaghetti & entangled monolithic legacy concerned every sufficiently large team. As a consequence, I got interested in static code analysis and started the project NDepend in 2004.
Nowadays NDepend is a full-fledged Independent Software Vendor (ISV). With more than 12.000 client companies, including many of the Fortune 500 ones, NDepend offers deeper insight and full control on their application to a wide range of professional users around the world.
I live with my wife and our twin kids Léna and Paul in the beautiful island of Mauritius in the Indian Ocean.
Recommend
-
200
本文发布在我的博客vue中慎用style的scoped属性许可协议: 署名-非商业性使用-禁止演绎4.0国际 转载请保留原文链接及作者。 在vue组件中,在style标签上添加scoped属性,以表示它的样式作用于当下的模块,很好的实现了样式私有化
-
63
PHP RFC: Namespace-scoped declares Version: 0.9 Date: 2016-09-20 Author: Nikita Popov
-
77
-
50
前言 文章原文地址:Nealyang/PersonalBlog 可能作为一个前端,在学习 Flutter 的过程中,总感觉非常非常相似 React Native,甚至于,其中还是...
-
61
Scoped Styles for React :warning: EARLY VERSION Get your CSS classes scoped by component directory Installation npm i react-scoped-styles
-
11
Introducing C# 10: File-scoped namespaces 2021-08-12 by anthonygiretti Introduction
-
5
C# 10.0 and .NET 6.0 will be released in November 2021. Time to look at the new language features with a little series of blog posts. Let’s start in this blog post with a very simple feature that is called
-
9
-
32
.NET Tools How-To's File-Scoped Namespaces – A Look at New Language Features in C#...
-
9
File Scoped Types in C# 11 Since the evaluation of C#, we have seen many access modifiers introduced, and similarly, in C# 11, file-scoped type is a new access modifier mainly designed for code generator authors where they can create a t...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK