Sunday 9 January 2022

a funny feature of VS' codelens

"It's not a bug, it's a feature". Present in VS Community 2019 since who knows when until at least January 2022.

Codelens shows the number of references to functions and properties, and if we click it, there is a nice menu of these that pops up and makes it easier to learn your (or someone else's) code structure. For some reason, it doesn't touch classes' fields. Ok, maybe it's more related to functions rather than fields. Or maybe we should use public properties rather than fields to communicate with class instances. Nevermind. I see no difference between a public field and a public property, except for the possibility that the latter can be actually a function. And public fields as such are abhorred by pros & gurus. They also make some difference when dealing with (de)serialization ans so on.

Somehow I didn't use "ordinary" inheritance and polymorphism much, but I fell in love with abstract classes. Mainly because of my laziness and lack of ability to control long code parts and strong hatred towards repeating code. The behavior of codelens in this respect fit well with what I had expected and was easy to understand—the number of references to an abstract function is at least the number of classes that inherit from your abstract class. And the number of references to each implementation of an abstract function is ... well, it's the number of times it's being called... Probably if you inherit from one of such classes and override the function further, this should add to the reference count. Ideally—above both the original abstract function and the "first" override. And these numbers cannot be equal.

But recently I had to add a common feature to many parts of GUI in some (not too clean) code, written mostly by random engineers (not CS engineers!). There are roughly 70+ of different not-main windows, so the easiest way of adding that feature (hiding or enabling buttons, menus etc. based on licence kind—from demo to full) was to add a private FeatureSetter void-lambda delegate to these windows' base class (there was one, luckily). Plus some trivial virtual FeatureSetterInit() function that I could then override in a non-trivial way in each window that needs that license-based behavior implemented, by adding something like

public override void FeatureSetterInit()
{
    FeatureSetter = (App.LicenseDetails) => 
    { 
        // show this button
        // hide that menu
        // ...
    };
}

And something wild happens here to codelens—it shows all references to the base function above the overriding functions in each of the inheriting classes. Each of these redefined functions are called exactly once, in a constructor of the window class that calls the overridden FeatureSetterInit() and then the FeatureSetter(). Why am I seeing 50+ references to a function that I know is called exactly once? Something went wrong, probably. I saw some similar bug reports, all have been given a `low priority' status. I wonder if this marvelous feature is shared by vscode.

I see no reason why this behavior should be so much different from that with definitions of functions that are somewhere higher declared as abstract. Yet. If it is the case, then it's a feature. Or there is no reason, then it's a bug.

No comments:

Post a Comment