I have a method that returns a tuple (string, MyEnum, MyObject?)
. There is one and only one enum value that means MyObject
is not null - all the others mean MyObject
will be null (and the string
will have a message).
Something along the lines of
(MyEnum response, Package? package) MyMethod()
{
if (Today == NiceDay)
{
return (MyEnum.Happy, new Package("I'm happy!"));
}
if (Today == RainyDay)
{
return (MyEnum.Pensive, null);
}
if (Today == SnowyDay)
{
return (MyEnum.Cold, null);
}
}
Obviously, if I try and use MyMethod().package.message
, the compiler will warn me about the possibility of a null reference. I'm aware of the null-forgiving operator, but that kind of feels like a quick-fix.
Is there a way to "tell" the compiler to expect a value when MyMethod().response
is MyEnum.Happy
, and null
when it is any other value, or is the null-forgiving operator the correct and expected way to deal with this situation?
CodePudding user response:
Currently attributes for null-state static analysis interpreted by the C# compiler does not support neither specifying nullability of selected properties of returned value nor scenario when specific constant/enum value can be tied to nullability of parameters (except bool
constants). The closest thing which can be done - return boolean value and tie out
parameter to the return:
bool MyMethod(out MyEnum response, [NotNullWhen(true)] out Package? package)
{
string Today = "";
response = MyEnum.Happy;
package = new Package("");
return true;
}
Usage:
if(MyMethod(out _, out var packageValue))
{
Console.WriteLine(packageValue.ToString()); // no warning
}
CodePudding user response:
So there are many ways to handle null/null warnings.
First
If you are 100% sure that the value cannot be null here you can use ! operator something like this package!.Message
Second
If You are not sure and there is only one condition in which the value can not be null its better to use the ternary operator like this var result = MyMethod().response == MyEnum.Happy ? MyMethod().package.message : string.Empty;
Third
you can use ?? operator like this var message = MyMethod().package?.message ?? "No message found";
or empty string according to your use case.
CodePudding user response:
As a suggestion to resolve the issue, instead of the null
have a static property in the Package
class that defines an empty package:
class Package {
public static Package None => new Package { Message = "No package." };
}
In your code make the return for Package non-nullable and use
return (MyEnum.Pensive, Package.None);
CodePudding user response:
When your Package object is null, package.Message
will break you application.
Just use null condition operator package?.Message
.