RefactorMCP catalog

Convert to File-Scoped Namespace

Turns a file's namespace Shop { ... } block into a namespace Shop; declaration, taking a level of indentation off the code inside.

Precondition

  • The project uses C# 10 or later.
  • The file has exactly one namespace declaration, a block, with no namespace nested inside it.
  • Nothing is declared outside the namespace, since a file-scoped namespace would take it in.

Transformation

  • The namespace line becomes namespace Name;, followed by a blank line, and the braces go. An opening brace on the namespace line is handled the same.
  • Every line inside the block loses one level of indentation, the file's own unit such as four spaces or a tab. This includes comments, documentation comments, indented directives such as #region, and using directives that were inside the namespace, which now follow the declaration.

Preserved

  • Everything before the namespace, such as a header comment and using directives.
  • Lines inside a string literal that spans lines, which are part of its value and keep their indentation.
  • Directives written at column zero, such as #if DEBUG.

Limitations

  • A comment between the namespace name and its opening brace, or after the closing brace on the same line, is dropped.

Error codes

CodeMeaning
no-block-namespacethe file has no namespace block, or its namespace is already file-scoped
several-namespacesthe file declares more than one namespace, side by side or nested
members-outside-namespacethe file declares code outside the namespace
language-versionthe project uses a language version before C# 10

Cases

·

Diffs show each file from before to after. /*[*/ … /*]*/ marks a selection and /*^*/ a caret; the runner removes them before the refactoring runs.

#already-file-scoped-refused

Refuses a file whose namespace is already file-scoped

refusal
TargetOrder.cs
Refusesno-block-namespace; every file is left unchanged
Order.csinput
1 namespace Shop;
2
3 public class Order
4 {
5 }

#block-namespace

Turns the file's namespace block into a file-scoped declaration and takes a level of indentation off its contents

success
TargetOrder.cs
Order.csmodified
11 using System;
22
3−namespace Shop.Orders
3+namespace Shop.Orders;
4+
5+public class Order
46 {
5− public class Order
7+ public DateTime Placed { get; set; }
8+
9+ public bool IsLate(DateTime now)
610 {
7− public DateTime Placed { get; set; }
8−
9− public bool IsLate(DateTime now)
10− {
11− return now - Placed > TimeSpan.FromDays(3);
12− }
13− }
14−
15− public enum Status
16− {
17− Open,
18− Closed,
11+ return now - Placed > TimeSpan.FromDays(3);
1912 }
2013 }
14+
15+public enum Status
16+{
17+ Open,
18+ Closed,
19+}

#brace-on-namespace-line

Handles an opening brace on the namespace line

success
TargetOrder.cs
Order.csmodified
1−namespace Shop {
2− public class Order {
3− public int Id { get; set; }
4− }
1+namespace Shop;
2+
3+public class Order {
4+ public int Id { get; set; }
55 }

#comments-and-directives

Keeps the header comment, usings inside the namespace, documentation comments and directives, dedenting all but column-zero directives

success
TargetOrder.cs
Order.csmodified
11 // Orders.
2−namespace Shop
2+namespace Shop;
3+
4+using System;
5+
6+/// <summary>
7+/// An order.
8+/// </summary>
9+public class Order
310 {
4− using System;
5−
6− /// <summary>
7− /// An order.
8− /// </summary>
9− public class Order
10− {
11− #region Dates
12− public DateTime Placed { get; set; } // local time
13− #endregion
11+ #region Dates
12+ public DateTime Placed { get; set; } // local time
13+ #endregion
1414
1515 #if DEBUG
16− public string Trace => "debug";
16+ public string Trace => "debug";
1717 #endif
1818
19− /* The day
20− after placing. */
21− public DateTime Next => Placed.AddDays(1);
22− }
19+ /* The day
20+ after placing. */
21+ public DateTime Next => Placed.AddDays(1);
2322 }

#language-version-refused

Refuses a project on a language version before C# 10

refusal
TargetOrder.cs
ProjectlangVersion 9
Refuseslanguage-version; every file is left unchanged
Order.csinput
1 namespace Shop
2 {
3 public class Order
4 {
5 }
6 }

#multiline-string-untouched

Leaves the lines inside a verbatim string as they were, since they are part of its value

success
TargetTemplate.cs
Template.csmodified
1−namespace Shop
1+namespace Shop;
2+
3+public static class Template
24 {
3− public static class Template
4− {
5− public const string Body = @"Dear customer,
5+ public const string Body = @"Dear customer,
66 Thank you.
77 Shop";
8− }
98 }

#nested-namespace-refused

Refuses a namespace that contains another namespace declaration

refusal
TargetModels.cs
Refusesseveral-namespaces; every file is left unchanged
Models.csinput
1 namespace Shop
2 {
3 namespace Legacy
4 {
5 public class OldOrder
6 {
7 }
8 }
9 }

#no-namespace-refused

Refuses a file with no namespace declaration

refusal
TargetOrder.cs
Refusesno-block-namespace; every file is left unchanged
Order.csinput
1 public class Order
2 {
3 }

#several-namespaces-refused

Refuses a file with more than one namespace declaration

refusal
TargetModels.cs
Refusesseveral-namespaces; every file is left unchanged
Models.csinput
1 namespace Shop
2 {
3 public class Order
4 {
5 }
6 }
7
8 namespace Shop.Legacy
9 {
10 public class OldOrder
11 {
12 }
13 }

#types-outside-namespace-refused

Refuses a file that declares a type outside the namespace, which would move into it

refusal
TargetModels.cs
Refusesmembers-outside-namespace; every file is left unchanged
Models.csinput
1 public class Global
2 {
3 }
4
5 namespace Shop
6 {
7 public class Order
8 {
9 }
10 }