ExhaustiveMatching
ExhaustiveMatching copied to clipboard
Dependency-free builds
I'd love to use this ExhaustiveMatching analyzer with a number of NuGet projects that I work on but I understand that even though this is a "private" dependency, it still causes my project to have a reference to the ExhaustiveMatching.dll assembly which then must be referenced by my output NuGet package - this isn't ideal.
It should be possible for the ExhaustiveMatching code-analysis to work by detecting the use of built-in exception types (e.g. ArgumentOutOfRangeException
) in a switch
block provided they're annotated with a known magic const string for the message:
ctor parameter - or allow use to redefine the ExhaustiveMatching
exceptions in our own projects - and the analyzer could then look for that without us needing to reference the ExhaustiveMatching.dll
assembly.
On a related note, I'd like to have two separate exceptions to : one derived from ArgumentOutOfRangeException
for when switching over an enum parameter argument, and another derived from InvalidOperationException
when swiching over an enum that isn't a parameter argument.
The library already supports exhaustive matching when throwing InvalidEnumArgumentException
which inherits from ArgumentOutOfRangeException
. It might be possible to split that functionality into a separate analyzer that doesn't add the dependency on ExhaustiveMatching.dll
.
The thing is that it isn't just the exception type in the ExhaustiveMatching.dll
. There are also the attributes used for closed types. Without that the functionality is severely limited. But it sounds as if you aren't using that functionality? In the future, there will likely be further useful types in there. For example, to configure null handling.
I'm not seeing a good way to support anything but the most basic stuff without the reference to ExhaustiveMatching.dll
.
@Jehoel, if ExhaustiveMatching.dll
were in a separate NuGet package so your NuGet package could depend on that without depending on ExhaustiveMatching.Analyzer
would that be good enough?
Redefining the ExhaustiveMatchFailedException
in your own library could make it strange for consumers of your library if it ever throws that exception.
The library already supports exhaustive matching when throwing
InvalidEnumArgumentException
which inherits fromArgumentOutOfRangeException
It doesn't. InvalidEnumArgumentException
inherits from only ArgumentException
.
There are also the attributes used for closed types. Without that the functionality is severely limited
It could be supported by simply requiring the project being analyzed to reimplement those types, just like how you can use C# 8.0 nullable annotations (which only exist in .NET Standard 2.1+ or .NET Core 3.0+) when targeting .NET Standard 2.0 by providing your own System.Diagnostics.CodeAnalysis.AllowNullAttribute
.
Redefining the
ExhaustiveMatchFailedException
in your own library could make it strange for consumers of your library if it ever throws that exception.
Whyso? The analyzer would presumably require that the project's ExhaustiveMatchFailedException
implementation must derive from ArgumentOutOfRangeException
so that catch(ArgumentException)
and catch(ArgumentOutOfRangeException)
still work as-expected.
I've decided on a plan for handling dependency-free builds. It is mostly described in the Packages and Downloading and Dependency Free Usage sections of the readme.
Additionally, I plan to actually eliminate the ExhaustiveMatchFailedException
exception. Instead only standard exceptions will be used. Which one is used will depend on whether the ExahustiveMatch.Failed<T>(string paramName, T value)
or ExahustiveMatch.Failed<T>(T value)
overload is used.
ExahustiveMatch.Failed<T>(string paramName, T value)
throws:
-
InvalidEnumArgumentException
for is an invalid enum value -
InvalidOperationException
fornull
value types (i.e.Nullable<T>
) - this should be prevented by the analyzer, if this happens it is not a problem with the argument, but with the matching. -
ArgumentNullException
fornull
reference types -
ArgumentOutOfRangeException
for all other cases - exception message will explain that exhaustive matching failed
ExahustiveMatch.Failed<T>(T value)
throws:
-
InvalidOperationException
for all cases - exception message will explain that exhaustive matching failed
I have not started implementing this. We will see how it goes.
I have this implemented in prototype form in my fork here: https://github.com/daiplusplus/ExhaustiveMatching/tree/dev/2023-11-look-mum-no-assembly-reference-required