I know this question has been asked multiple times before, but I've checked all I could not find any solution there, because none of this specifically handles/talks about nullable types.
Use case
I want to generate test data dynamically. To do this the value
I pass in can have different types and I need to convert it (via CreateSomething
) in some data type e.g. a specially formatted string. For this, I have the helper function shown below.
An example would be to generate an example XML file for later use in testing against the system in production. The value
is then used to assert the correct expected output.
Note that for some types I need special handling, such as converting bools to integers (as you can see below), that's why I need a switch. In addition, the egnerated string mentions the type of the test data (though it does not match all types you have in C#/uses other names, e.g. booleans are defined as integers).
Possible example
With C# 8.0 this is possible:
public static string GetSomething(object? value) =>
value switch
{
bool boolValue => CreateSomething("Integer", boolValue
? 1
: 0),
string stringValue => CreateSomething("String", stringValue),
int numericValue => CreateSomething("String", numericValue.ToString()),
null => CreateSomething("String", value),
_ => throw new ArgumentOutOfRangeException(nameof(value))
};
CreateSomething
is defined as this:
string CreateSomething(string customType, object? value)
Question
However, as for the null
case (maked above), I further want to handle the type.
As you can see with the other cases, I want to pass Integer
in there for all bool
values as the first parameter, and String
for all others.
Of course, the value
is and stays null
, but that is about to be expected, I just want to keep the information/pass the information on about what type it should expect/define the thing in my test data, because otherwise it is defined as another data type and thus does not produce as real test data as it could (without disregarding the type).
Tries
I thought of using a second switch statement in there/or use .GetType
, but of course that doe snot work as .GetType
on null
throws a NullReferenceException
.
I also looked at getting the underlying type of a nullable via Nullable.GetUnderlyingType(value)
, but that did not work either. And this question to get the type from null
only has answers using Generics, which I don't want in my case.
After all, I do have this nice C# switch type pattern matching statement I can use for all types - why can't I also use it for nullable types?
Idea solution
After all, this would be ideal:
/* Code does not work! Only demonstration! */
public static string GetSomething(object? value) =>
value switch
{
bool? boolValue => CreateSomething("Integer", boolValue == null
? null : (boolValue ? 1 : 0),
string? stringValue => CreateSomething("String", stringValue),
int? numericValue => CreateSomething("String", numericValue?.ToString()),
_ => throw new ArgumentOutOfRangeException(nameof(value))
};
Of course, I tried that and it also did not work.
It just shows me the error CS8400 ("Feature type pattern is not available in C# 8.0. Please use language version 9.0 or higher.") and "Type test pattern requires variable designation or discard after.". And even if I use C# 9 it breaks the syntax while not showing me any explicit compiler error anymore.