codemaid icon indicating copy to clipboard operation
codemaid copied to clipboard

Reorganize backing fields on top of the matching property

Open Der-Kraken opened this issue 6 years ago • 9 comments

Environment

  • Visual Studio version: Visual Studio 2017 Professional
  • CodeMaid version: v10.5
  • Code language: C#

Description

When reorganize the code then the code get's grouped by field, property, methods and so on. That's a perfect behaviour except for backing fields.

It would be wonderful if a backing field gets put above their property pendant. In the examples below the backing field is the member '_floatingValue'. That should be placed always above 'FloatingValue'.

Steps to recreate

public class MyClass
{
    // Fields

    private int _number = 1;

    // Properties

    public string Alpha { get; set; }

    private float _floatingValue;
    public float FloatingValue
    {
        get { return _floatingValue; }
        set { _floatingValue = value; }
    }
}

Current behavior (after click "Reorganize Active Document")

public class MyClass
{
    // Fields

    private float _floatingValue;
    private int _number = 1;

    // Properties

    public string Alpha { get; set; }
    public float FloatingValue
    {
        get { return _floatingValue; }
        set { _floatingValue = value; }
    }
}

Expected behavior

public class MyClass
{
    // Fields

    private int _number = 1;

    // Properties

    public string Alpha { get; set; }

    private float _floatingValue;
    public float FloatingValue
    {
        get { return _floatingValue; }
        set { _floatingValue = value; }
    }
}

Der-Kraken avatar Jul 19 '18 13:07 Der-Kraken

Thanks for the suggestion, that's an interesting idea. It would likely require Roslyn for some more sophisticated code analysis than string matching approaches we use today. One question it would raise is how "complex" could the getter/setter be before it's no longer recognized as a backing field scenario. Examples:

get { return Alpha == string.Empty ? 0 : _floatingValue; }
get { Debug.WriteLine(_floatingValue); return _floatingValue; }

codecadwallader avatar Jul 28 '18 14:07 codecadwallader

Hello,

I think string matching by the naming would work. If the code has crazy property logic (like the example below) roslyn should not have a chance to find the correct backing field.

public float FloatingValue
{
	get { return _number / _floatingValue; }
	set
	{
		_number = (int)value;
		_floatingValue = _number;
	}
}

For the name matching by string there could be several options to find the pendant.

  • Look for the most common conventions (e.g. number, _number, _Number, ...)
  • Analyse the VS17 settings for code conventions (Options->Text Editor->C#->Code Style->->Naming)
  • or custom format rules in CodeMaid-Options

Der-Kraken avatar Jul 30 '18 06:07 Der-Kraken

If you could just sort properties and fields together as a unit alphabetically, that would be a simple fix. I thought it would to that when I merged the properties and fields sections in options but sadly they're still segregated...

ekolis avatar Aug 23 '18 01:08 ekolis

@ekolis that's an interesting idea, and you can already customize CodeMaid to sort properties and fields together (go to CodeMaid->Options->Reorganizing->Types and drag one on top of the other to merge them together). The secondary sort is alphabetical though so _floatingValue1, _floatingValue2, FloatingValue1 and FloatingValue2 are going to sort in that order.

codecadwallader avatar Aug 25 '18 12:08 codecadwallader

@codecadwallader I tried that option but it still puts all the properties above all the fields; it doesn't merge them. I'm using the camelCase convention for backing fields, not _underscores, so I don't know why it's not working... maybe it's using ASCII sort (all capitals before all lowercase) rather than alphabetical sort?

ekolis avatar Aug 25 '18 13:08 ekolis

Yes, it's using a standard string CompareTo function. https://github.com/codecadwallader/codemaid/blob/master/CodeMaid/Helpers/CodeItemTypeComparer.cs#L55

codecadwallader avatar Aug 26 '18 13:08 codecadwallader

Hi there, Any progress here? :)

Simon755 avatar Jan 23 '20 12:01 Simon755

If this is still an open issue, I'd solve the problem you raise by convention. If the property is Foo then the backing variable must either be foo or _foo. Anything else is not the backing variable for this purpose.

JesseLiberty avatar Aug 15 '22 14:08 JesseLiberty

Just chiming in to resurrect this issue and say that I too would very much like this feature, as I like to keep my backing fields next to my properties.

JesseLiberty's suggestion of simply going with the convention where property names are PascalCase and their backing fields would be matching with either camelCase or _camelCase would work well, as that convention is widely accepted.

So, Property PersonId would match with personId or _personId.

This is also inline with the source generators used in the Mvvm Community Toolkit (source code generation for ObservableProperties only works with fields that are of form camelCase, _camelCase, or m_camelCase).

misterkiem avatar Nov 22 '23 04:11 misterkiem