RefactorMCP catalog

Change Accessibility

Changes the declared accessibility of a type or member, refusing when that would break a reference, an override or an interface implementation, or quietly change what a call binds to.

Arguments

ArgumentMeaning
accessibilitypublic, internal, protected, private, protected internal or private protected

The target is the type or member, by symbol.

Precondition

  • The accessibility is one of the six C# accessibilities, and is valid for the declaration: a top-level type cannot be private or protected, and an explicit interface implementation takes none.
  • Every reference can still see the declaration.
  • An override keeps the accessibility of the member it overrides, so neither a virtual member with overrides nor an override can change alone.
  • A member implementing an interface member implicitly stays public.
  • Accessibility stays consistent: a type used in the signature of a member cannot become less accessible than that member.
  • The declaration is referenced exactly as often as before. Accessibility takes part in overload resolution, so hiding an overload can send its calls to another one, and exposing one can take calls from another, with the code still compiling.
  • A field is the only one its declaration declares.

Transformation

  • The accessibility keywords are replaced where they stood, and the other modifiers stay in their order.
  • A declaration with no accessibility written gets one in front of its other modifiers, after its attributes and documentation comment.
  • Every part of a partial type that states an accessibility changes; parts that state none are left to take it from the others.

Preserved

  • What every reference binds to.
  • Documentation comments, attributes, and comments between modifiers.

Limitations

  • Accessor accessibility, such as a private set, is not covered.
  • Members of interfaces are not covered.
  • An override family is refused rather than changed together.
  • References from other assemblies outside the solution, such as those that see internal members through InternalsVisibleTo or consume a published package, are not considered.

Error codes

CodeMeaning
invalid-accessibilitythe argument is not a C# accessibility
breaks-referencesa reference could no longer see the declaration
breaks-overridean override and the member it overrides would disagree
breaks-interface-implementationan implicit interface implementation would not be public
inconsistent-accessibilitya member's signature would use a less accessible type
changes-bindinga call would bind to a different member
shared-declarationthe field is declared together with others

Cases

·

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

#breaks-interface-implementation-rejected

Refuses to narrow a method that implicitly implements an interface member

refusal
Targetsymbol M:Shop.Courier.Cost(System.Decimal)
Arguments
accessibility"internal"
Refusesbreaks-interface-implementation; every file is left unchanged
Courier.csinput
1 namespace Shop;
2
3 public interface IShipping
4 {
5 decimal Cost(decimal weight);
6 }
7
8 public class Courier : IShipping
9 {
10 public decimal Cost(decimal weight)
11 {
12 return weight * 2m;
13 }
14 }

#breaks-override-rejected

Refuses to change a virtual method whose override must keep the same accessibility

refusal
Targetsymbol M:Shop.Notifier.Format(System.String)
Arguments
accessibility"public"
Refusesbreaks-override; every file is left unchanged
Notifier.csinput
1 namespace Shop;
2
3 public class Notifier
4 {
5 protected virtual string Format(string message)
6 {
7 return message;
8 }
9 }
10
11 public class LoudNotifier : Notifier
12 {
13 protected override string Format(string message)
14 {
15 return message + "!";
16 }
17 }

#breaks-references-rejected

Refuses to make a method private while another class calls it

refusal
Targetsymbol M:Shop.Order.Tax
Arguments
accessibility"private"
Refusesbreaks-references mentioning “Invoice.cs”; every file is left unchanged
Invoice.csinput
1 namespace Shop;
2
3 public class Invoice
4 {
5 public decimal Total(Order order)
6 {
7 return 100m + order.Tax();
8 }
9 }
Order.csinput
1 namespace Shop;
2
3 public class Order
4 {
5 public decimal Tax()
6 {
7 return 20m;
8 }
9 }

#changes-binding-rejected

Refuses when a caller would still compile but call another overload

refusal
Targetsymbol M:Shop.Printer.Print(System.String)
Arguments
accessibility"private"
Refuseschanges-binding; every file is left unchanged
Printer.csinput
1 namespace Shop;
2
3 public class Printer
4 {
5 public string Print(object value)
6 {
7 return "object";
8 }
9
10 public string Print(string value)
11 {
12 return "string";
13 }
14 }
15
16 public class Label
17 {
18 public string Show(Printer printer)
19 {
20 return printer.Print("sale");
21 }
22 }

#generic-type

Makes a generic class public, with its constructed uses in another file unchanged

success
Targetsymbol T:Shop.Box`1
Arguments
accessibility"public"
Box.csmodified
11 namespace Shop;
22
3−internal class Box<T>
3+public class Box<T>
44 {
55 public T Item { get; set; }
66 }
Packer.csunchanged
11 namespace Shop;
22
33 internal class Packer
44 {
55 public Box<int> Pack(int value)
66 {
77 return new Box<int> { Item = value };
88 }
99 }

#inconsistent-accessibility-rejected

Refuses to make a type internal while a public method returns it

refusal
Targetsymbol T:Shop.Money
Arguments
accessibility"internal"
Refusesinconsistent-accessibility; every file is left unchanged
Money.csinput
1 namespace Shop;
2
3 public class Money
4 {
5 public decimal Amount { get; set; }
6 }
7
8 public class Till
9 {
10 public Money Total()
11 {
12 return new Money();
13 }
14 }

#invalid-accessibility-rejected

Refuses a word that is not a C# accessibility

refusal
Targetsymbol M:Shop.Order.Tax
Arguments
accessibility"friend"
Refusesinvalid-accessibility; every file is left unchanged
Order.csinput
1 namespace Shop;
2
3 public class Order
4 {
5 public decimal Tax()
6 {
7 return 20m;
8 }
9 }

#keeps-other-modifiers-and-comments

Replaces only the accessibility of a field, keeping its other modifiers, its comment and its documentation

success
Targetsymbol F:Shop.Limits.Maximum
Arguments
accessibility"private"
Limits.csmodified
11 namespace Shop;
22
33 public class Limits
44 {
55 /// <summary>The largest basket.</summary>
6− internal /* shared */ static readonly int Maximum = 3;
6+ private /* shared */ static readonly int Maximum = 3;
77
88 public bool Allows(int count)
99 {
1010 return count <= Maximum;
1111 }
1212 }

#narrow-with-references-in-another-file

Narrows a public method to internal when its only callers are in the same assembly

success
Targetsymbol M:Shop.Order.Tax
Arguments
accessibility"internal"
Order.csmodified
11 namespace Shop;
22
33 public class Order
44 {
5− public decimal Tax()
5+ internal decimal Tax()
66 {
77 return 20m;
88 }
99 }
Invoice.csunchanged
11 namespace Shop;
22
33 public class Invoice
44 {
55 public decimal Total(Order order)
66 {
77 return 100m + order.Tax();
88 }
99 }

#no-modifier-with-attribute

Adds an accessibility to a member that had none, after its attribute and documentation comment

success
Targetsymbol M:Shop.Counter.Reset
Arguments
accessibility"internal"
Counter.csmodified
11 using System;
22
33 namespace Shop;
44
55 public class Counter
66 {
77 /// <summary>Starts again from zero.</summary>
88 [Obsolete("Use Clear")]
9− void Reset()
9+ internal void Reset()
1010 {
1111 }
1212 }

#partial-type

Changes a partial class on the part that states its accessibility, leaving the part that states none

success
Targetsymbol T:Shop.Basket
Arguments
accessibility"internal"
Basket.csmodified
11 namespace Shop;
22
3−public partial class Basket
3+internal partial class Basket
44 {
55 public int Count { get; set; }
66 }
Basket.Items.csunchanged
11 namespace Shop;
22
33 partial class Basket
44 {
55 public void Add()
66 {
77 Count++;
88 }
99 }

#private-method-to-public

Makes a private method public

success
Targetsymbol M:Shop.Order.Tax
Arguments
accessibility"public"
Order.csmodified
11 namespace Shop;
22
33 public class Order
44 {
55 public decimal Total()
66 {
77 return 100m + Tax();
88 }
99
10− private decimal Tax()
10+ public decimal Tax()
1111 {
1212 return 20m;
1313 }
1414 }

#shared-declaration-rejected

Refuses a field declared together with another, which would need splitting first

refusal
Targetsymbol F:Shop.Point.X
Arguments
accessibility"private"
Refusesshared-declaration; every file is left unchanged
Point.csinput
1 namespace Shop;
2
3 public class Point
4 {
5 public int X, Y;
6 }

#two-word-accessibility

Writes a two-word accessibility in place of a one-word one

success
Targetsymbol M:Shop.Report.Header
Arguments
accessibility"protected internal"
Report.csmodified
11 namespace Shop;
22
33 public class Report
44 {
5− private string Header()
5+ protected internal string Header()
66 {
77 return "Report";
88 }
99
1010 public string Print()
1111 {
1212 return Header();
1313 }
1414 }