Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refactor C# automatic properties to fields and getter/setter property?

Tags:

c#

refactoring

I have a bunch of business class with autoproperties :

public class A {

    public int Id { get; set; }
    public string Title { get; set;}

}

Because the application evolves, there is a new requirement to enable tracking the changes of the properties, in order to send to the backing store only changed data.

In order to reach this goal, I have to convert ALL properties to field + property like this :

public class A {

    private int m_Id;
    public int Id {
        get { return m_Id; }
        set {
            if(m_Id != value){
                SetChanged("Id");
                m_Id = value;
            }
        }
    }
    private string m_Title;
    public string Title 
    { 
        get { return m_Title; }
        set {
            if(m_Title != value){
                SetChanged("Title");
                m_Title = value;
            }
        }
    }

    protecte void SetChanged(string propertyName) { 
        // Not important here
    }
}

Is there a way to quickly refactor my code to avoid having to manually change the properties ?

like image 903
Steve B Avatar asked Oct 08 '22 07:10

Steve B


1 Answers

There's no way in the IDE to do this, but if you need to replace all X properties, I would write a short console application to do it.

The process would be:

  • Iterate over all files in directory matching *.cs
  • Foreach file, regex find and replace old property for new property syntax

Using regex to match is very powerful. Regex can be used in VS2010 to do a find/replace operation. If you try finding this (with regex enabled)

{(public|private|internal|protected)}:b{[a-zA-Z0-9]+}
:b{[a-zA-Z0-9]+}:b\{ get; set; \}

It will match properties like this

public Type Foo { get; set; }

In your console application find all lines of code that match the above, then start splitting them up into Modifier, Type, Property Name and finally replacing the whole block with something like this

// PS: this is pseudocode ;-) or could be your new property template
private [Type] m_[PropertyName].ToPascaleCase
public [Type] PropertyName
{
    get { return m_[PropertyName].ToPascaleCase; }
    set
    {
        if(m_[PropertyName].ToPascaleCase != value){
            SetChanged([PropertyName]);
            m_[PropertyName].ToPascaleCase = value;
        }
    }
}

Finally I would advocate taking a backup of your code or running this test offline and testing before checking in!!

like image 93
Dr. Andrew Burnett-Thompson Avatar answered Oct 10 '22 07:10

Dr. Andrew Burnett-Thompson