In Oct 2017 I wrote about the potential collision problem with extension methods. At that time the .NET Framework 4.7.1 was just released with this new extension method that is colliding with our own NDepend.API Append() extension method with same signature.
1 |
System.Linq.Enumerable.Append<TSource>(this System.Collections.Generic.IEnumerable<TSource>, TSource) |
The problem was solved easily because just one default rule consumed our Append() extension method, we just had to refactor this method to use it as a static method call instead of an extension method call: ExtensionMethodsEnumerable.Append(...)
Unfortunately with the recent release of .NET Framework 4.7.2, the same problem just happened again, this time with this extension method:
1 |
System.Linq.Enumerable.ToHashSet<TSource>(this System.Collections.Generic.IEnumerable<TSource>) |
This time 22 default code rules are relying on our ToHashSet() extension method. This method is used widely because it is often the cornerstone to improve significantly performances. But this means that after installing the .NET Fx v4.7.2, 22 default rules will break.
This time the problem is not solved easily by calling our ExtensionMethodsSet.ToHashSet<TSource>(this IEnumerable<TSource>) extension method as a static method because in most of these 22 rules source code, changing the extension method call into a static method call require a few brain cycle. Moreover it makes the rules source code less readable: For example the first needs to be transformed into the second:
1 2 |
let disposeMethods = disposableTypes.ChildMethods().WithName("Dispose()").ToHashSet() let disposeMethods = ExtensionMethodsSet.ToHashSet(disposableTypes.ChildMethods().WithName("Dispose()")) |
We wanted a straightforward and clean way for NDepend users to solve this issue on all their default-or-custom code rules. The solution is the new extension method ToHashSetEx().
Solving the issue on an existing NDepend deployment is now as simple as replacing .ToHashSet() with .ToHashSetEx() in all textual files that contain the user code rules and code queries (the files with extension .ndproj and .ndrules).
We just released NDepend v2018.1.1 with this new extension method ExtensionMethodsSet.ToHashSetEx<TSource>(this IEnumerable<TSource>). Of course all default rules and generated queries now rely on ToHashSetEx() and also a smart error message is now shown to the user in such situation:
We hesitated between ToHashSetEx() and ToHashSet2() but we are confident that this problem won’t scale (more explanation on suffixing a class or method name with Ex here).
Actually we could have detected this particular problem earlier in October 2017 because Microsoft claimed that the .NET Fx will ultimately support .NET Standard 2.0 and .NET Standard 2.0 already presented this ToHashSet() extension method. So this time we analyzed both C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\netstandard.dll and NDepend.API.dll to double-check with this code query that there is no more risk of extension method collision:
1 2 3 4 5 |
// <Name>List extension methods with same name declared in different assemblies</Name> let lookup = Application.Methods.Where(m => m.IsExtensionMethod).ToLookup(m => m.SimpleName) from l in lookup where l.ParentAssemblies().Count() > 1 select new { method = l.First(), overloads =l.ToArray() } |
We find back both Append() and ToHashSet() collisions and since NDepend.API is not concerned with queryable, there is no more risk of collision:
I liked as much as you’ll receive carried out right here.
The caricature is attractive, your authored subject matter stylish.
however, you command get bought an impatience over that
you wish be delivering the following. in poor health for sure come further in the past again as precisely the same nearly a
lot regularly inside of case you defend this increase. http://mysticmanbeardoil.net/