RefactorMCP catalog

Safe Delete Type

Deletes a class, struct, record, interface, enum or delegate that nothing uses, and the file it was alone in.

Precondition

  • Nothing outside the type's own declarations refers to it, in any project of the solution: not as a variable, parameter or return type, not in a base list, not by new, typeof or nameof.
  • Nothing outside refers to its members either. Extension methods are called without naming their class, so a static class whose extension methods are in use is not deleted.

Transformation

  • Every declaration of the type is removed with its documentation comment: each part of a partial type, wherever it is.
  • A file left with nothing declared in it is deleted, whatever using directives it had. A file that declares other types keeps them, one blank line apart as before.
  • A namespace block left empty is removed with it.
  • A nested type is removed from its containing type like any member.

Preserved

  • Every other type, including a type of the same name with a different number of type parameters.
  • Preprocessor directives around the declaration.

Limitations

  • Uses by reflection, serialization or string names are not found.
  • A file that keeps only assembly attributes or global using directives is kept.

Error codes

CodeMeaning
type-referencedcode outside the type refers to it or to one of its members

Cases

·

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

#base-class-refused

Refuses to delete a class that another class derives from

refusal
Targetsymbol T:Shop.Entity
Refusestype-referenced; every file is left unchanged
Entities.csinput
1 namespace Shop
2 {
3 public abstract class Entity
4 {
5 }
6
7 public class Order : Entity
8 {
9 }
10 }

#extension-methods-in-use-refused

Refuses to delete a static class whose extension methods are called, though its name appears nowhere else

refusal
Targetsymbol T:Shop.StringExtensions
Refusestype-referenced; every file is left unchanged
Greeter.csinput
1 namespace Shop
2 {
3 public class Greeter
4 {
5 public string Greet(string name) => name.Shout();
6 }
7 }
StringExtensions.csinput
1 namespace Shop
2 {
3 public static class StringExtensions
4 {
5 public static string Shout(this string text) => text.ToUpperInvariant();
6 }
7 }

#file-scoped-namespace

Deletes an unused interface and its file when the file uses a file-scoped namespace

success
Targetsymbol T:Shop.IAuditor
IAuditor.csdeleted
1−namespace Shop;
2−
3−public interface IAuditor
4−{
5− void Record(string entry);
6−}
Order.csunchanged
11 namespace Shop;
22
33 public class Order
44 {
55 }

#generic-type

Deletes an unused generic class that refers to itself, leaving the non-generic class of the same name

success
Targetsymbol T:Shop.Box`1
Boxes.csmodified
11 namespace Shop
22 {
33 public class Box
44 {
5− }
6−
7− public class Box<T>
8− {
9− public T Item { get; set; }
10−
11− public Box<T> Copy() => new Box<T> { Item = Item };
125 }
136
147 public class Shelf
158 {
169 public Box First { get; } = new Box();
1710 }
1811 }

#last-type-in-namespace

Deletes an unused class and the namespace block it leaves empty, keeping the other namespace in the file

success
Targetsymbol T:Shop.Legacy.OldCart
Carts.csmodified
11 namespace Shop
22 {
33 public class Cart
44 {
55 }
66 }
7−
8−namespace Shop.Legacy
9−{
10− public class OldCart
11− {
12− }
13−}

#nested-type

Deletes an unused nested class

success
Targetsymbol T:Shop.Order.Draft
Order.csmodified
11 namespace Shop
22 {
33 public class Order
44 {
55 public int Id { get; set; }
6−
7− private class Draft
8− {
9− }
106 }
117 }

#only-type-in-file

Deletes an unused class and the file that held only it

success
Targetsymbol T:Shop.LegacyPricing
LegacyPricing.csdeleted
1−using System;
2−
3−namespace Shop
4−{
5− public class LegacyPricing
6− {
7− public decimal Price(decimal amount) => Math.Round(amount, 2);
8− }
9−}
Order.csunchanged
11 namespace Shop
22 {
33 public class Order
44 {
55 }
66 }

#partial-type-across-files

Deletes every part of an unused partial class and the files that held only its parts

success
Targetsymbol T:Shop.Report
Report.Rendering.csdeleted
1−namespace Shop
2−{
3− public partial class Report
4− {
5− public string Render() => Title.ToUpperInvariant();
6− }
7−}
Report.csdeleted
1−namespace Shop
2−{
3− public partial class Report
4− {
5− public string Title { get; set; } = "";
6− }
7−}
Order.csunchanged
11 namespace Shop
22 {
33 public class Order
44 {
55 }
66 }

#referenced-from-another-project-refused

Refuses to delete a class a referencing project uses

refusal
Targetsymbol T:Core.Product
ProjectsCore; App → Core
Refusestype-referenced; every file is left unchanged
App/Catalog.csinput
1 namespace App
2 {
3 public class Catalog
4 {
5 public Core.Product Create() => new Core.Product();
6 }
7 }
Core/Product.csinput
1 namespace Core
2 {
3 public class Product
4 {
5 }
6 }

#referenced-in-another-file-refused

Refuses to delete a class another file uses

refusal
Targetsymbol T:Shop.Customer
Refusestype-referenced mentioning “Order.cs”; every file is left unchanged
Customer.csinput
1 namespace Shop
2 {
3 public class Customer
4 {
5 }
6 }
Order.csinput
1 namespace Shop
2 {
3 public class Order
4 {
5 public Customer Buyer { get; set; }
6 }
7 }

#type-among-others

Deletes an unused class with its documentation comment from a file that declares other types

success
Targetsymbol T:Shop.Coupon
Models.csmodified
11 namespace Shop
22 {
33 public class Customer
44 {
55 }
66
7− /// <summary>A discount code.</summary>
8− public class Coupon
9− {
10− public string Code { get; set; } = "";
11− }
12−
137 public class Address
148 {
159 }
1610 }