I use null to denote that an optional parameter A? a of a function should assume a non-null default value, computed in the function. After entering the function, I check whether the passed-in argument a is null, and if so, assign a a non-null value. From that point on, it can safely be assumed that a is non-null. The problem: the compiler is not aware of this, and now I have to refer to a.Value for the rest of the function, instead of the straightforward a.
Is there a way to tell the compiler that a is actually non-null from some point on? If not, what is the clearest way to deal with such optional parameters?
Example code:
using System;
namespace test
{
public struct A { public int x; };
class Program
{
static void f(A? a = null)
{
// Assign the default value.
if (a == null) a = new A { x = 3 };
// Now 'a' is non-null for the rest of the function.
// What I do now:
Console.WriteLine(a.Value.x);
// What I'd like to do:
// * Mark 'a' as non-null somehow.
// Now can refer to 'a' directly:
// Console.WriteLine(a.x);
}
static void Main(string[] args)
{
f();
}
}
}
>Solution :
It looks like you just want to allow the method to be called without specifying a parameter (and use a certain default in that case).
There is another possible solution to this particular scenario:. Just overload f() like so:
static void f()
{
f(new A { x = 3 });
}
static void f(A a)
{
Console.WriteLine(a.x);
}
Code can then call f() with or without a parameter, but the difference is that in the case where it calls f(A a) with a parameter, it cannot be null.
(In response to your comment below.)
If you want to handle being able to call with a possibly-null struct, you can overload like this instead:
static void f(A? a = default)
{
f(a ?? new A { x = 3 });
}
static void f(A a)
{
Console.WriteLine(a.x);
}
That means your implementation doesn’t have to deal with a possibly-null value, but you can still omit the argument at the call site, or call it with a null value.
Note: You can simplify static void f(A? a = default) to:
static void f(A? a = default) => f(a ?? new A { x = 3 });
if you prefer the shorter syntax.