Skip to content

Commit 96d8b5d

Browse files
committed
publish spec and add preprocessor reference
First commit: Publish the C# speclet for ignored preprocessor directives, and make the updates for the ignored directives used for file based programs.
1 parent ee28614 commit 96d8b5d

File tree

3 files changed

+66
-2
lines changed

3 files changed

+66
-2
lines changed

docfx.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@
6161
"partial-events-and-constructors.md",
6262
"null-conditional-assignment.md",
6363
"extensions.md",
64-
"user-defined-compound-assignment.md"
64+
"user-defined-compound-assignment.md",
65+
"ignored-directives.md"
6566
],
6667
"src": "_csharplang/proposals",
6768
"dest": "csharp/language-reference/proposals",
@@ -533,7 +534,7 @@
533534
"_csharplang/proposals/csharp-11.0/*.md": "09/30/2022",
534535
"_csharplang/proposals/csharp-12.0/*.md": "08/15/2023",
535536
"_csharplang/proposals/csharp-13.0/*.md": "10/31/2024",
536-
"_csharplang/proposals/*.md": "04/08/2025",
537+
"_csharplang/proposals/*.md": "06/19/2025",
537538
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md": "11/08/2022",
538539
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 8.md": "11/08/2023",
539540
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 9.md": "11/09/2024",
@@ -713,6 +714,7 @@
713714
"_csharplang/proposals/null-conditional-assignment.md": "Null conditional assignment",
714715
"_csharplang/proposals/extensions.md": "Extension members",
715716
"_csharplang/proposals/user-defined-compound-assignment.md": "User-defined compound assignment",
717+
"_csharplang/proposals/ignored-directives.md": "Ignored preprocessor directives",
716718
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md": "C# compiler breaking changes since C# 10",
717719
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 8.md": "C# compiler breaking changes since C# 11",
718720
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 9.md": "C# compiler breaking changes since C# 12",
@@ -838,6 +840,7 @@
838840
"_csharplang/proposals/null-conditional-assignment.md": "This proposal allows the null conditional operator to be used for the destination of assignment expressions. This allows you to assign a value to a property or field only if the left side is not null.",
839841
"_csharplang/proposals/extensions.md": "This proposal enables new kinds of extension members. These new extension members support extension properties, extension static members, including extension operators.",
840842
"_csharplang/proposals/user-defined-compound-assignment.md": "This proposal introduces user-defined compound assignment operators. Developers can override compound assignment, increment, and decrement operators.",
843+
"_csharplang/proposals/ignored-directives.md": "This proposal allows a source file to include ignored directives. In most cases, ignored directives are used for file based programs, for example `#!`",
841844
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md": "Learn about any breaking changes since the initial release of C# 10 and included in C# 11",
842845
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 8.md": "Learn about any breaking changes since the initial release of C# 11 and included in C# 12",
843846
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 9.md": "Learn about any breaking changes since the initial release of C# 12 and included in C# 13",

docs/csharp/language-reference/preprocessor-directives.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ f1_keywords:
2020
- "#pragma warning"
2121
- "#pragma checksum"
2222
- "defaultline_CSharpKeyword"
23+
- "#!"
24+
-
2325
helpviewer_keywords:
2426
- "preprocessor directives [C#]"
2527
- "keywords [C#], preprocessor directives"
@@ -43,6 +45,63 @@ helpviewer_keywords:
4345

4446
Although the compiler doesn't have a separate preprocessor, the directives described in this section are processed as if there were one. You use them to help in conditional compilation. Unlike C and C++ directives, you can't use these directives to create macros. A preprocessor directive must be the only instruction on a line.
4547

48+
## File based programs
49+
50+
*File based programs* are programs that are compiled and run using `dotnet run Program.cs` (or any `*.cs` file). These preprocessor directives are ignored by the C# compiler, but are parsed by the build system to produce the output. These directives will generate warnings when encountered in a project-based compilation.
51+
52+
The C# compiler ignores any preprocessor directive that starts with `#:` or `#!`.
53+
54+
The `#!` preprocessor directive enables unix shells to directly execute a C# file using `dotnet run`. For example:
55+
56+
```csharp
57+
#!/usr/bin/dotnet run
58+
Console.WriteLine("Hello");
59+
```
60+
61+
The preceding code snippet informs a unix shell to execute the file using `/usr/bin/dotnet run`. The `#!` line must be the first line in the file, and the following tokens are the program to run. You'll need to enable the *execute* (`x`) permission on the C# file for that feature.
62+
63+
The `#:` directives that are used in file based programs include:
64+
65+
- `#:sdk`:
66+
67+
The first instance specifies the value for the `<Project Sdk="value" />` node. Subsequent instances specify `<Sdk Name="value" Version="version" />` node. The version may be omitted. For example:
68+
69+
```csharp
70+
#:sdk Microsoft.NET.Sdk.Web
71+
```
72+
73+
- `#:property`:
74+
75+
Instances of `#:property` are translated into property elements in a `<PropertyGroup>`. A token of the form `Name=value` must follow the `property` token. The following a valid `property` tokens:
76+
77+
```csharp
78+
#:property TargetFramework=net11.0
79+
#:property LangVersion=preview
80+
```
81+
82+
The preceding two properties are translated into:
83+
84+
```xml
85+
<TargetFramework>net11.0</TargetFramework>
86+
<LangVersion>preview</LangVersion>
87+
```
88+
89+
- `#:package`:
90+
91+
Instances `#:package` are translated into `PackageReference` elements to include NuGet packages with the specifieid version to your file. For example:
92+
93+
```csharp
94+
#:package [email protected]*
95+
```
96+
97+
The preceding preprocessor token is translated into:
98+
99+
```xml
100+
<PackageReference Include="System.CommandLine" Version="2.0.0-*">
101+
```
102+
103+
Tools may add new tokens following the `#:` convention.
104+
46105
## Nullable context
47106

48107
The `#nullable` preprocessor directive sets the *annotations* and *warning* flags in the *nullable context*. This directive controls whether nullable annotations have effect, and whether nullability warnings are given. Each flag is either *disabled* or *enabled*.

docs/csharp/specification/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ items:
7979
href: ../../../_csharplang/proposals/csharp-10.0/enhanced-line-directives.md
8080
- name: "Escape sequence '\\e'"
8181
href: ../../../_csharplang/proposals/csharp-13.0/esc-escape-sequence.md
82+
- name: "Ignored directives"
83+
href: ../../../_csharplang/proposals/ignored-directives.md
8284
- name: Basic concepts
8385
items:
8486
- name: Top-level statements

0 commit comments

Comments
 (0)