Author |
Topic |
|
Uniwares
Tomato Guru
Portugal
2322 Posts |
Posted - Jun 01 2020 : 05:28:11 AM
|
I am currently using quite alot of extension methods (own and from libraries) and I am seeing an unwelcome side effect in VA: extension methods are shown preceeding class members.
Here for example, the class has 3 properies, yet they dont show immediately, focus is on the possible extension methods.
I think that members should ALWAYS have priority.
|
Edited by - Uniwares on Jun 01 2020 05:30:48 AM |
|
accord
Whole Tomato Software
United Kingdom
3287 Posts |
Posted - Jun 02 2020 : 11:09:31 PM
|
Does it make any difference if you tick VA Options -> Enhanced Listboxes -> List non-inherited entries first? |
|
|
Uniwares
Tomato Guru
Portugal
2322 Posts |
Posted - Jun 03 2020 : 04:10:56 AM
|
Its checked, point is, members are listed first but focus is always on the extension methods (see the scroll bar in the screen shot) |
|
|
feline
Whole Tomato Software
United Kingdom
19021 Posts |
Posted - Jun 03 2020 : 10:40:46 AM
|
Since I am not really familiar with C# extension methods, I started with the documentation. Based on the first paragraph here:
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods
and specifically the sentence "For client code written in C#, F# and Visual Basic, there's no apparent difference between calling an extension method and the methods defined in a type.", it looks like the listbox is behaving fairly correctly and normally.
If you disable VA does the listbox behave differently? I am wondering if what you are seeing is the standard IDE behaviour or not. I am organizing a test case here, but am also trying to understand how extension methods should be treated in listboxes. |
zen is the art of being at one with the two'ness |
|
|
feline
Whole Tomato Software
United Kingdom
19021 Posts |
Posted - Jun 03 2020 : 11:54:07 AM
|
OK, some interesting results. For ease, this is the test code that I am using, and I have just been testing this on VS2019, on a system where VA has never been installed.
namespace c_sharp_class_library.TestExtensionMethods
{
class SimpleDataType
{
// Auto-implemented properties
public string Name { get; set; }
public string Colour { get; set; }
public short Height { get; set; }
}
static class MyExtensions
{
public static int LengthOfName(this SimpleDataType data) { return data.Name.Length; }
public static bool ShouldBeAssignableTo(this SimpleDataType data, SimpleDataType rhs) { return false; }
public static bool ShouldBeGreaterThan(this SimpleDataType data, SimpleDataType rhs) { return false; }
public static bool ShouldBeGreaterThanOrEqualTo(this SimpleDataType data, SimpleDataType rhs) { return false; }
public static bool ShouldBeLessThan(this SimpleDataType data, SimpleDataType rhs) { return false; }
public static bool ShouldBeLessThanOrEqualTo(this SimpleDataType data, SimpleDataType rhs) { return false; }
}
class testUsingExtensionMethods
{
void simpleTests()
{
SimpleDataType localData = new SimpleDataType();
Console.WriteLine(localData.LengthOfName());
Console.WriteLine(localData.ShouldBeGreaterThan(localData));
localData.|
}
}
}
On first copy and paste of the following code into a file, so the first time the IDE is asked to produce a listbox at the caret, |, the first item in the listbox has partial focus, "Colour" in this case. But after calling "ShouldBeGreaterThan", the next time the listbox appears this extension method has focus. The same happens when calling "Height" or "ToString".
The default item in the listbox is the last called member, regardless of if it is an extension method or not. I am seeing the same behaviour here, with VA installed and active. |
zen is the art of being at one with the two'ness |
|
|
Uniwares
Tomato Guru
Portugal
2322 Posts |
Posted - Jun 04 2020 : 08:46:25 AM
|
quote: The default item in the listbox is the last called member, regardless of if it is an extension method or not. I am seeing the same behaviour here, with VA installed and active.
Problem here is that from here on, the last used extension method is default for ANY class where it can apply, its kinda right considering that this method may not be bound to the class where I last used it, but totally wrong considering that I may not even write anymore in the same class.
Example, using Shoudly:
class a { public int Member1; }
class b { public int Member2; }
// somewhere else
a aa = new a();
b bb = new b();
aa.Member1 = 0;
aa.Member1.ShouldBe(0);
bb.| // here its messed up, because not Member2 comes as default but ShouldBe()
Hope I made myself understandable? |
|
|
feline
Whole Tomato Software
United Kingdom
19021 Posts |
Posted - Jun 04 2020 : 11:19:34 AM
|
I see. You get the same behaviour with VA completely disabled, so it seems safe to say this is default IDE behaviour.
I am trying to decide how to describe / define the desired behaviour here. When generating a listbox for a different type, don't focus on the extension methods by default. But if so, what should get focus? I suppose the first not inherited member should have default focus here. Does this sound right?
I suspect this problem is "specific" to Shouldly, and anywhere else where extension methods are applied to every single type. |
zen is the art of being at one with the two'ness |
|
|
Uniwares
Tomato Guru
Portugal
2322 Posts |
Posted - Jun 04 2020 : 11:29:07 AM
|
Your approach sounds reasonable. I got to try without VA to get a feeling how VS handles it. And yes, it should apply to any extension method. Actually, maybe extension methods should be excluded from being default, even if used frequently (an setting maybe?). |
|
|
Uniwares
Tomato Guru
Portugal
2322 Posts |
Posted - Jun 04 2020 : 11:37:50 AM
|
What I see here is that VS suggests the last used extension method with a star in front, default, but all members of the class right under it, and THEN the rest of the extension methods that apply to this class. |
|
|
feline
Whole Tomato Software
United Kingdom
19021 Posts |
Posted - Jun 05 2020 : 06:23:31 AM
|
Just to make sure that I am testing the right thing, I have now moved to a clean machine, VA never installed. I am seeing the * marked item, but I noticed that the rest of the extension methods are actually listed in alphabetical order. So, I changed the test slightly, to use the classes:
class a
{
public int Member1;
public int WideMember1;
}
class b
{
public int Member2;
public int WideMember2;
} here, when you get to "bb." the extension methods from Shouldly are listed before the second member item of the class.
So I am starting to wonder if instead we want an option to always place extension methods at the bottom of the listbox, similar to the list non inherited items first. But even if done so, this won't, by its self, fix the problem with the default item being an extension method some of the time.
Shouldly really makes it a little more complex to define "good" default behaviour here |
zen is the art of being at one with the two'ness |
|
|
Uniwares
Tomato Guru
Portugal
2322 Posts |
Posted - Jun 05 2020 : 06:54:06 AM
|
Shouldly is not the only large extension method library, although one of the larger ones (LINQ itself is a large one). I think that extension methods ALWAYS after everything else is something expectable (they are also marked with their own icon), if there is a default one some of the time (like starred ones) thats ok, as long as the other class members show up around it and are not hidden among 200+ extension methods.
I think the biggest complication of Shouldly is that its so generic and applies to ALL types, whereas LINQ is bound to a limited amount of types. |
|
|
feline
Whole Tomato Software
United Kingdom
19021 Posts |
Posted - Jun 05 2020 : 10:44:00 AM
|
I have put in a feature request for a setting to place extension methods at the end of the listbox, to see what our developers make of this:
case=142330 |
zen is the art of being at one with the two'ness |
|
|
|
Topic |
|