RefactorMCP catalog

Refactoring catalog

Every refactoring RefactorMCP aims to support, described as behaviour and specified by fixtures: a compilable before, the operation, and the exact after.

136refactorings
1570cases
720refusal cases

Primitives 100

Single, behaviour-preserving transformations.

Add Delegating Member

Adds to a class a member that forwards to the member of the same name of one of its fields, or of its base class. Replace Inheritance with Delegation uses it to give a class, while it still derives from its base class, its own members for the inherited ones other code uses, so the class can later stop deriving without its callers noticing.

add-delegating-member20 cases9 refusals

Add Default Value to Parameter

Makes a parameter optional by giving it a default value, and optionally drops the arguments that pass that same value.

add-parameter-default-value11 cases5 refusals

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.

change-accessibility14 cases7 refusals

Change Base Type

Sets, replaces or removes the base class of a class. Extract Superclass and Replace Inheritance with Delegation use it to move a class under a new parent or off an old one.

change-base-type17 cases9 refusals

Change Return Type

Changes the declared return type of a method, and of every override, interface member and implementation that must match it, when the method's body and every caller stay valid.

change-return-type13 cases6 refusals

Change Signature

Adds, removes and reorders the parameters of a method or constructor, and updates every call in the solution to match. Overrides, overridden methods, interface members and their implementations change together, since they must keep the same parameters.

change-signature24 cases10 refusals

Change Type

Changes the declared type of a local, parameter, field, property or method return value, typically to a base type or interface its uses need ("use base type where possible"). Introduce Interface for Dependency uses it after Extract Interface.

change-type13 cases6 refusals

Cleanup Usings

Removes the using directives in a file that nothing in it needs.

cleanup-usings6 cases

Consolidate Duplicate Conditional Fragments

Moves statements that every branch of a conditional starts or ends with out of the conditional, so they are written once.

consolidate-duplicate-conditional-fragments9 cases6 refusals

Convert Anonymous Type to Class

Replaces an anonymous type with a named class that behaves the same, and constructs that class wherever the containing member creates the anonymous type.

convert-anonymous-type-to-class8 cases4 refusals

Convert Auto-Property to Property with Backing Field

Gives an auto-property an explicit private field and accessors that read and write it, so the accessors can later gain behaviour. The reverse of Convert to Auto-Property.

convert-auto-property-to-backing-field8 cases3 refusals

Convert Class to Record

Turns a class whose state is fixed by its constructor into a record: a positional record where the constructor only assigns its parameters to get-only properties, otherwise the same members with class changed to record.

convert-class-to-record16 cases9 refusals

Convert String Concatenation to Interpolation

Turns a chain of + string concatenations into one interpolated string: "Hello, " + name + "!" becomes $"Hello, {name}!".

convert-concatenation-to-interpolation17 cases3 refusals

Convert Extension Method to Static Method

The reverse of Convert to Extension Method: an extension method becomes an ordinary static method, and every extension-style call becomes a static call.

convert-extension-method-to-static5 cases2 refusals

Convert For to Foreach

Turns an index loop that only reads each element of a collection in turn into a foreach over the collection: for (int i = 0; i < items.Count; i++) with items[i] in the body becomes foreach (T item in items) with item. The reverse of Convert Foreach to For.

convert-for-to-foreach13 cases7 refusals

Convert Foreach to For

Turns a foreach over an indexable collection into an index loop that reads each element into the loop's variable: foreach (var item in items) becomes for (int i = 0; i < items.Count; i++) with var item = items[i]; as the first statement of the body. The reverse of Convert For to Foreach.

convert-foreach-to-for15 cases4 refusals

Convert Foreach to LINQ

Turns a foreach loop that builds a list, a total, a count or a flag from a sequence into a LINQ query in method syntax. The reverse of Convert LINQ to Foreach.

convert-foreach-to-linq18 cases6 refusals

Convert If Chain to Switch Statement

Turns an if / else if chain that compares one value with constants or patterns into a switch statement on that value.

convert-if-chain-to-switch9 cases5 refusals

Convert Lambda to Method Group

Replaces a lambda that only passes its parameters on to a method, such as n => Format(n), with the method group Format. The reverse of Convert Method Group to Lambda.

convert-lambda-to-method-group14 cases6 refusals

Convert LINQ to Foreach

Turns a LINQ query of Where and Select ending in ToList, Sum, Count or Any into a foreach loop that builds the same result. The reverse of Convert Foreach to LINQ.

convert-linq-to-foreach18 cases5 refusals

Convert Local Function to Method

Moves a local function out of its member to a private method of the containing type. Variables it captures become parameters. The reverse of Convert Method to Local Function.

convert-local-function-to-method17 cases5 refusals

Convert Local to Field

Promotes a local variable to a private field of the containing type. The declaration becomes an assignment to the field and every use refers to the field. A step of Replace Method with Method Object.

convert-local-to-field14 cases7 refusals

Convert Method Group to Lambda

Replaces a method group used as a delegate, such as Format, with a lambda calling it, such as number => Format(number). The reverse of Convert Lambda to Method Group.

convert-method-group-to-lambda14 cases4 refusals

Convert Method to Local Function

Moves a private method used by only one member into that member as a local function. The reverse of Convert Local Function to Method.

convert-method-to-local-function17 cases8 refusals

Convert Method to Property

Turns a parameterless method that returns a value, such as GetTotal(), into a get-only property, and every call into a property read.

convert-method-to-property14 cases7 refusals

Convert Primary Constructor to Constructor

Replaces a class or struct's primary constructor with an explicit constructor, storing each captured parameter in a private field.

convert-primary-constructor-to-constructor8 cases3 refusals

Convert Property to Methods

Replaces a property with a Get method and, when it has a setter, a Set method, and turns every read and write into a call.

convert-property-to-methods11 cases6 refusals

Convert Record to Class

Turns a record into a class that behaves the same: a positional record's constructor, properties and Deconstruct are written out, and the value equality, ToString and == operators the compiler generated for the record are generated as source.

convert-record-to-class11 cases5 refusals

Convert Setter to Init-Only

Replaces a property's set accessor with an init accessor, so the property can only be set while the object is being created.

convert-setter-to-init8 cases4 refusals

Convert Switch Expression to Switch Statement

Turns a switch expression that is the whole value of a return, an assignment or a local's initialiser into a switch statement.

convert-switch-expression-to-statement8 cases3 refusals

Convert Switch Statement to Switch Expression

Turns a switch statement whose every section produces a value into a switch expression that is returned or assigned.

convert-switch-statement-to-expression8 cases4 refusals

Convert to Auto-Property

Replaces a property whose accessors only read and write a private field with an auto-property, and removes the field.

convert-to-auto-property10 cases4 refusals

Convert to Block Body

Replaces an expression body with a block holding the equivalent statement. The reverse of Convert to Expression Body.

convert-to-block-body18 cases4 refusals

Convert to Block Namespace

Turns a file's namespace Shop; declaration into a namespace Shop { ... } block around everything after it, indenting that code a level. The reverse of Convert to File-Scoped Namespace.

convert-to-block-namespace4 cases1 refusal

Convert to Expression Body

Replaces a block body holding a single statement with an expression body. The reverse of Convert to Block Body.

convert-to-expression-body19 cases6 refusals

Convert to Extension Method

Makes a method callable as an extension method on the type of its first parameter.

convert-to-extension-method8 cases3 refusals

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.

convert-to-file-scoped-namespace10 cases6 refusals

Convert to Primary Constructor

Replaces a constructor that only hands its parameters to fields and properties with a C# 12 primary constructor. Private fields that merely hold a parameter are removed and their uses read the parameter directly; other members are initialized from it.

convert-to-primary-constructor13 cases7 refusals

Convert Tuple to Named Type

Replaces a tuple in a method's signature, its return type or one of its parameters, with a named positional record, and updates the method's body and its callers to construct and read it.

convert-tuple-to-named-type9 cases5 refusals

Create Type

Creates an empty class, interface, record or struct, either in a new file or at the end of an existing one. Composite recipes such as Extract Class and Extract Superclass start with it, so it takes no target, only arguments.

create-type14 cases5 refusals

Encapsulate Collection

Stops callers changing a type's list behind its back: the list is exposed as a read-only view, and the type gains Add and Remove methods for the changes it allows.

encapsulate-collection9 cases4 refusals

Encapsulate Field

Makes a field private behind a property that reads and writes it, and points code outside the declaring type at the property.

encapsulate-field9 cases4 refusals

Extract Interface

Declares some or all of a class's public members in a new interface, in a new file, and makes the class implement it. Introduce Interface for Dependency uses it before changing the type of a field or parameter to the interface.

extract-interface11 cases4 refusals

Extract Local Variable

Also known as Introduce Variable. Declares a local holding a selected expression just before the statement that contains it, and uses the local in place of the expression. The reverse of Inline Local Variable.

extract-local-variable15 cases8 refusals

Extract Method

Moves a run of statements, or a single expression, out of a method body into a new private method, and replaces them with a call to it.

extract-method25 cases10 refusals

Initialize Field from Constructor Parameter

Assigns a field that nothing uses yet from a constructor parameter, at the end of the constructor. Nothing reads the field, so the assignment changes nothing the code does; it prepares the field for a later step, such as Replace Expression with Field in Constructor Injection's recipe.

initialize-field-from-constructor-parameter12 cases6 refusals

Inline Constant

Replaces every use of a constant field, across the solution, with its value and removes the constant.

inline-constant6 cases2 refusals

Inline Field

Replaces every read of a field that is only ever assigned by its initialiser with that initialiser, across the solution, and removes the field.

inline-field7 cases3 refusals

Inline Local Variable

Replaces every use of a local with the expression it was initialised with, and removes the declaration. The reverse of Extract Local Variable.

inline-local-variable13 cases7 refusals

Inline Method

Replaces every call of a method with the method's body, across the solution, and deletes the method. The reverse of Extract Method. A read-only property whose getter computes its value is inlined the same way at every read.

inline-method29 cases14 refusals

Inline Parameter

When every call passes the same constant for a parameter, removes the parameter and writes the constant where the body used it.

inline-parameter11 cases5 refusals

Inline Type Alias

Writes the type an alias names in place of every use of the alias and removes the alias's using directive. The reverse of Introduce Type Alias.

inline-type-alias6 cases2 refusals

Introduce Constant

Replaces a selected literal or constant expression with a named constant of the containing type, and optionally every other occurrence of the same value in that type. The catalog's answer to a magic number.

introduce-constant7 cases3 refusals

Introduce Field

Stores the value of a selected expression in a new field of the containing type and uses the field in its place. A second form adds a field of a named type to a type, which composite recipes such as Extract Class use to hold the object that members move to.

introduce-field13 cases6 refusals

Introduce Generic Type Parameter

Replaces a concrete type used in a class or method with a new type parameter, constrained as the uses need, and passes the old type wherever the class or method is used, so every existing use means what it did.

introduce-generic-type-parameter14 cases6 refusals

Introduce Parameter

Turns an expression in a method body into a new parameter. The expression is replaced by the parameter, and every call passes the expression instead, computed from that call's own arguments.

introduce-parameter11 cases5 refusals

Introduce Type Alias

Declares a using alias for a type written in a file, such as using StockIndex = System.Collections.Generic.Dictionary<string, System.Collections.Generic.List<int>>;, and writes the alias wherever the file names that type.

introduce-type-alias7 cases4 refusals

Introduce Using Declaration

Turns a using statement whose block runs to the end of its enclosing block into a C# 8 using declaration followed by the block's statements:

introduce-using-declaration16 cases7 refusals

Invert Boolean

Inverts the meaning of a bool field, property, method or local: renames it, gives it the negation of every value it was given, and negates every use, so that IsEnabled can become IsDisabled without changing behaviour.

invert-boolean15 cases8 refusals

Invert If

Negates the condition of an if statement and swaps its branches.

invert-if14 cases3 refusals

Join Declaration and Assignment

Joins a local declaration that has no initializer with the first assignment to the local: T x; followed by x = e; becomes T x = e;. The reverse of Split Declaration and Assignment.

join-declaration-and-assignment9 cases6 refusals

Make Field Readonly

Adds readonly to a field that is only assigned while an object is being constructed, so the compiler enforces what the code already does.

make-field-readonly10 cases4 refusals

Make Method Async

Makes a method that blocks on tasks async: it awaits them instead and returns a task. Its callers get the task, and block on it where they used to get the value, so only the method itself changes shape. Convert to Async repeats this on each caller up to a boundary.

make-method-async14 cases7 refusals

Make Method Instance

The reverse of Make Method Static with pass: instance: a static method that takes an instance of its own type becomes an instance method on that parameter.

make-method-instance8 cases5 refusals

Make Method Static

Turns an instance method into a static method of the same class, and updates every call across the solution to pass what the method used to take from the instance.

make-method-static10 cases5 refusals

Make Type Partial

Adds the partial modifier to a class, struct, record or interface, so its members can be spread over several declarations.

make-type-partial7 cases2 refusals

Merge Nested If

Joins an if whose only statement is another if into a single if on both conditions: if (a) { if (b) { S } } becomes if (a && b) { S }.

merge-nested-if9 cases5 refusals

Merge Partial Declarations

Moves the members of every part of a partial type into one of its declarations, deleting the parts and any file they leave empty.

merge-partial-declarations8 cases2 refusals

Merge Sibling Ifs

Joins an if with the if after it when both have the same body, into one if on both conditions: if (a) { S } else if (b) { S } and if (a) { return; } if (b) { return; } become if (a || b) { S } and if (a || b) { return; }. The counterpart of Merge Nested If, which joins with &&.

merge-sibling-ifs10 cases4 refusals

Move Field

Moves a field to another type. An instance field moves onto the type of another field or property of its class (the "via") and is reached through it, or into the class that holds its class (into), whose uses went through that holder; a static field or constant moves to a named type.

move-field15 cases8 refusals

Move Instance Method

Moves an instance method onto the type of one of its class's fields or properties, or of one of its own parameters. That field, property or parameter (the "via") becomes this in the method's new home. Or, with into, moves it the other way: into the class that holds its class in a field or property (the "holder"), which it then reaches the rest of its old class through.

move-instance-method22 cases11 refusals

Move Member to Another Partial File

Moves a member of a partial type into the part of that type declared in another file, or into a new file holding a new part.

move-member-to-partial-file8 cases3 refusals

Move Property

Moves a property to another type. An instance property moves onto the type of a field or property of its class (the "via") and is reached through it, or into the class that holds its class (into), whose uses went through that holder; a static property moves to a named type.

move-property9 cases5 refusals

Move Static Method

Moves a static method to another type, named by the caller, creating that type as a static class when it does not exist.

move-static-method9 cases4 refusals

Move Type to File

Moves a top-level type out of a file that declares several types into a new file of its own, named after the type, in the same folder and project.

move-type-to-file9 cases3 refusals

Move Type to Namespace

Changes the namespace a top-level type is declared in, leaving it in its file, and keeps every reference to it compiling across the solution.

move-type-to-namespace11 cases4 refusals

Pull Up Constructor Body

Moves the statements at the start of a subclass constructor that only set up the base class into a base constructor, and makes the subclass constructor chain to it.

pull-up-constructor-body12 cases5 refusals

Pull Up Field

Moves a field from a class into its base class. The other subclasses that declare the same field lose their copy, since they now inherit it.

pull-up-field11 cases5 refusals

Pull Up Method

Moves a method from a class into its base class, or declares it abstract in the base class and makes the subclasses' versions override it.

pull-up-method13 cases6 refusals

Push Down Field

Moves a field from a class into the direct subclasses that need it: those whose code uses it, or whose callers reach it through a reference of the subclass's type. When nothing uses the field, every direct subclass gets a copy, so the declaration is never lost.

push-down-field12 cases5 refusals

Push Down Method

Moves a method from a class into the direct subclasses that need it: those whose code calls it, or whose callers reach it through a reference of the subclass's type. When nothing calls it, every direct subclass gets a copy. An abstract method is removed instead, and each subclass's implementation stays as an ordinary method.

push-down-method14 cases7 refusals

Redirect Calls with Constant Argument

Makes calls that pass a constant for a parameter call, directly, the method the original runs for that value. When SetValue(string name, int value) calls SetHeight(value) for "height", box.SetValue("height", 10) becomes box.SetHeight(10). Replace Parameter with Explicit Methods uses it once the branches have methods of their own.

redirect-calls-with-constant-argument17 cases8 refusals

Remove Delegating Member

Removes a member that only forwards, through base, to the inherited member it hides or overrides, so its callers reach the inherited member directly. Replace Delegation with Inheritance uses it once a class's forwarding members reach their targets through base.

remove-delegating-member15 cases5 refusals

Remove Redundant Else

Removes the else of an if whose branch always jumps away, so the else's statements follow the if: if (a) { return A(); } else { B(); } becomes if (a) { return A(); } followed by B();.

remove-redundant-else11 cases5 refusals

Remove Unused Parameter

Removes a parameter that no body reads, together with the argument every call passes for it.

remove-unused-parameter8 cases3 refusals

Rename

Gives a symbol a new name and updates every reference to it across the solution.

rename17 cases4 refusals

Rename File to Match Type

Renames a source file after the single top-level type it declares, so that Ledger.cs holding class Account becomes Account.cs.

rename-file-to-match-type7 cases3 refusals

Replace Base Uses with Field

For a class that derives from another and holds a new instance of it in a private field: the class's own uses of the members it inherits go through the field instead, so nothing uses the part of the instance its base class makes up. Replace Inheritance with Delegation uses it just before removing the base class.

replace-base-uses-with-field17 cases12 refusals

Replace Constructor with Factory Method

Adds a static factory method that calls a constructor, narrows the constructor, and makes every creation in the solution call the factory.

replace-constructor-with-factory-method10 cases5 refusals

Replace Expression with Field

Replaces an expression in a member with a readonly field that holds an equivalent value: every constructor assigns the field from a parameter, and every construction of the class passes an equivalent expression for that parameter. Constructor Injection's recipe uses it to replace the object a method constructs with the one the class receives.

replace-expression-with-field17 cases10 refusals

Replace Field Uses with Base

For a class that derives from another and also holds a new instance of it in a private field: uses of the field's members become uses of the members the class inherits, and the field is removed, so the instance itself takes the field's place. Replace Delegation with Inheritance uses it once the class derives from the field's class.

replace-field-uses-with-base18 cases12 refusals

Safe Delete Local

Deletes a local variable that nothing uses, keeping whatever its initializer did beyond producing a value.

safe-delete-local9 cases4 refusals

Safe Delete Member

Deletes a method, property, indexer, field or event that nothing uses.

safe-delete-member13 cases7 refusals

Safe Delete Type

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

safe-delete-type11 cases4 refusals

Split Declaration and Assignment

Turns a local declaration with an initializer into a declaration without one, followed by an assignment of the same value: var x = e; becomes T x; and x = e;. The reverse of Join Declaration and Assignment.

split-declaration-and-assignment11 cases6 refusals

Split If

Splits an if whose condition is joined by && or || into two if statements, the reverse of Merge Nested If and of Consolidate Conditional Expression.

split-if7 cases3 refusals

Split Temporary Variable

Gives a local that is reassigned for an unrelated purpose a new local from that reassignment on. The assignment becomes the declaration of a new local, and the uses after it refer to the new local. Applied once per reassignment, it leaves one local per purpose.

split-temporary-variable12 cases7 refusals

Sync Namespace with Folder

Sets the namespace of a file to the one its location implies: the project's root namespace followed by the folders between the project and the file. Billing/Taxes/Rate.cs in a project whose root namespace is Shop gets the namespace Shop.Billing.Taxes.

sync-namespace-with-folder7 cases4 refusals

Use Named Arguments

Names the arguments of one call after the parameters they are passed for.

use-named-arguments11 cases4 refusals

Use Pattern Matching

Replaces a type test followed by casts, or an as conversion followed by a null check, with a declaration pattern in the if statement.

use-pattern-matching14 cases7 refusals

Composites 24

Refactorings built as a recipe of primitive steps.

Collapse Hierarchy

Merges a class and its base class into one when they are no longer different enough to be kept apart: a subclass into its base class, or a base class into its only subclass.

collapse-hierarchy16 cases11 refusals

Consolidate Conditional Expression

Combines a run of conditions that lead to the same code into one condition, and optionally gives it a name by extracting it into a method.

consolidate-conditional-expression16 cases6 refusals

Constructor Injection

Turns an object a method constructs for itself into a dependency the class receives through its constructor and keeps in a field. Every construction of the class passes a new instance, built as the method built it.

constructor-injection6 cases3 refusals

Convert If to Switch Expression

Turns an if / else if chain that compares one value with constants or patterns, and whose branches each produce a value, into a switch expression that is returned or assigned.

convert-if-to-switch-expression9 cases4 refusals

Convert to Async

Makes a method that blocks on tasks async: it awaits them instead and returns a task. Its callers await it and become async in turn, repeating up to callers that cannot be async, which go on blocking on the task.

convert-to-async6 cases3 refusals

Decompose Conditional

Extracts the condition of an if statement into a method that names it, and each branch into a method that names what it does, so the statement reads as a sentence.

decompose-conditional9 cases5 refusals

Extract Class

Splits a class that does two jobs: some of its fields, properties and methods move into a new class, and the old class keeps a field holding an instance of it and reaches the moved members through that field.

extract-class8 cases5 refusals

Extract Superclass

Gives a class a new base class and moves some of its fields and methods up into it, so that other classes can later share them by deriving from it too.

extract-superclass7 cases4 refusals

Hide Delegate

Stops clients reaching through one object to another. When clients write person.Department.Manager, the person gains a Manager member that forwards to its department, and the clients write person.Manager, so they no longer depend on the department.

hide-delegate7 cases4 refusals

Inline Class

Moves every member of a class that is not pulling its weight into the one class that holds an instance of it, and deletes it. The reverse of Extract Class.

inline-class15 cases7 refusals

Introduce Interface for Dependency

Makes a class depend on an interface instead of a concrete class: the interface is extracted from the concrete class, and the field, property or parameter holding the dependency is declared as the interface. Callers keep passing the concrete class, which now implements the interface.

introduce-interface-for-dependency6 cases3 refusals

Introduce Parameter Object

Replaces a group of parameters that travel together with one parameter of a new positional record holding them. The body reads the record's properties, and every call builds the record from the arguments it passed.

introduce-parameter-object7 cases4 refusals

Make Static then Move

Moves an instance method to another class as a static method that takes the instance as a parameter. Useful for moving a method out of a large class when it has no field or parameter of the target type to move through.

make-static-then-move5 cases2 refusals

Move Multiple Methods

Moves several methods of a class to another type in one operation: each instance method through a field, property or parameter of the target type, each static method to the target type by name.

move-multiple-methods5 cases2 refusals

Parameterise Method

Replaces several methods that do the same thing with different literal values by one method that takes those values as parameters, and makes every call pass the values of the method it called.

parameterise-method7 cases4 refusals

Preserve Whole Object

Replaces parameters that every call fills from members of one object with a single parameter taking the object, and reads the members in the body.

preserve-whole-object8 cases5 refusals

Remove Middle Man

Removes the members of a class that only pass requests on to another object it holds, so that callers talk to that object directly. The reverse of Hide Delegate.

remove-middle-man8 cases4 refusals

Replace Delegation with Inheritance

For a class that holds an object of another class and forwards most of its members to it: the class derives from the other class instead, the members that only forwarded are removed so the inherited ones take their place, and the field goes.

replace-delegation-with-inheritance10 cases8 refusals

Replace Inheritance with Delegation

For a class that inherits from another only to reuse some of its members: the class holds an instance of its old base class in a field, reaches what it used to inherit through the field, forwards the inherited members other code uses, and stops deriving from the old base class.

replace-inheritance-with-delegation9 cases6 refusals

Replace Method with Method Object

Turns a long method whose locals get in the way of Extract Method into an object of its own. The instance, each parameter and each local become fields of a new class, so the body can then be split into methods that share them without passing them around. The old method creates one of these objects for each call and runs it.

replace-method-with-method-object15 cases11 refusals

Replace Nested Conditional with Guard Clauses

Flattens nested conditionals so that each special case is checked by a guard clause that leaves early, and the normal path runs unindented after them.

replace-nested-conditional-with-guard-clauses12 cases3 refusals

Replace Parameter with Explicit Methods

Gives each value a method dispatches on a method of its own, and makes calls that pass the value as a constant call that method directly. SetValue("height", 10) becomes SetHeight(10).

replace-parameter-with-explicit-methods6 cases3 refusals

Replace Temp with Query

Replaces a local variable that holds the result of an expression with a private method that computes it, and calls the method wherever the local was read.

replace-temp-with-query11 cases6 refusals

Separate Query from Modifier

Splits a method that both changes state and returns a value into a modifier that makes the change and a query that returns the value, and makes every caller call both. Afterwards asking for the value no longer changes anything.

separate-query-from-modifier8 cases5 refusals

Generators 12

Refactorings that generate new structure around existing code.

Add Null Checks

Adds an argument null guard at the start of a method or constructor for each reference-type parameter that is meant never to be null.

add-null-checks9 cases2 refusals

Add Observer / Event

Declares an event on a method's class and raises it whenever the method completes, so other objects can observe the change the method makes without the class knowing about them.

add-observer9 cases4 refusals

Convert to Nullable-Aware

Enables nullable reference types in one file and adds the ? annotations its code shows it needs, so the file compiles without new warnings. Files are converted one at a time, so a project can move to nullable gradually.

convert-to-nullable-aware8 cases3 refusals

Create Adapter

Generates an adapter: a class that implements an interface a client expects by wrapping an existing class, the adaptee, and forwarding each interface member to the adaptee member that does the same job.

create-adapter12 cases5 refusals

Extract Decorator

Generates a decorator for an interface: a class that implements the interface, wraps another implementation of it, and forwards every member to the wrapped instance. Behaviour is then added by editing the decorator's members, and callers opt in by wrapping an instance.

extract-decorator12 cases3 refusals

Feature Flag Wrapping

Replaces an if on a feature flag with strategies: each branch moves into the Apply method of its own class, and a property named after the flag checks it and returns the strategy to apply. The flag then decides between two objects in one place instead of guarding code inline, and the old path can later be deleted by deleting a class.

feature-flag-wrapping13 cases8 refusals

Introduce Null Object

Generates a class that implements a field's interface by doing nothing, makes the field hold it instead of null, and removes the field's null checks across the solution.

introduce-null-object13 cases6 refusals

Replace Array with Object

Replaces an array whose elements mean different things, such as a name at index 0 and a score at index 1, with a new class that has a named property for each index.

replace-array-with-object14 cases8 refusals

Replace Conditional with Polymorphism

Replaces a method whose body chooses what to do by the kind of object it is dealing with, with a method each subclass overrides. The conditional can test either:

replace-conditional-with-polymorphism13 cases6 refusals

Replace Error Code with Exception

Makes a method that reports failure through its return value return nothing and throw instead, and turns each caller that tested the value into a try/catch.

replace-error-code-with-exception13 cases7 refusals

Replace Type Code with Enum

Replaces a set of int or string constants that name kinds of something, such as Employee.Engineer = 0 and Employee.Manager = 1, with an enum, and retypes every declaration that carries one of those codes.

replace-type-code-with-enum11 cases5 refusals

Replace Type Code with Subclasses

Replaces an enum field that says what kind of object an instance is with a subclass per kind. Each object's class then carries its kind, so Replace Conditional with Polymorphism can move the behaviour that switches on it into the subclasses.

replace-type-code-with-subclasses12 cases6 refusals