x is object
is being advanced as the canonical null check for C# 8, with x is not null
planned for the future. The reason is that the compiler warns when is object
is a no-op (when used on a non-nullable value type). However, one of the main reasons to use x is { }
is something that is object
can't do: introduce a new variable. I might want to introduce a new variable when the x
expression is more complex and I don't want to repeat it. Also, nullableFoo is { } foo
allows me to use foo
instead of nullableFoo.Value
.
I started using is object
instead of is { }
while slightly skeptical that I'd ever notice the difference, but now I've run into real-world x is { } y
code that shows that the compiler warning would have helped.
Currently, using x is { } y
means giving up that useful warning (SharpLab):
class C
{
void M(int value)
{
// โ CS0183: The given expression is always of the provided ('object') type
_ = value is object;
// No diagnostic ๐ข
_ = value is { };
// No diagnostic ๐ข
_ = value is { } foo;
}
}
Parity with is object
would be amazing:
class C
{
void M(int value)
{
// โ CS0472: The result of the expression is always 'true' since a value of type 'int'
// is never equal to 'null' of type 'int?'
// โโโโโโโโโโโโ
_ = value is { };
// โ CS0472: The result of the expression is always 'true' since a value of type 'int'
// is never equal to 'null' of type 'int?'
// ๐ Use 'is var'
// โโโโโโโโโโโโ
_ = value is { } foo;
}
}
Definitely would be useful. I use is {}
as the canonical notnull check for brevity, clarity vs is object
, and consistency between patterns that declare a subvariable and those that don't.
It would be great to have this warning.
Keep in mind that compiler warnings will appear in both regular and generated code. I would be especially concerned about the value is { } x
case, since it's purely a code style change.
I'm also concerned about encouraging the use of value is var x
unless we _also_ have the ability to detect cases where the static type of value
is a reference type, which means either nullable reference types is enabled or we have some other analyzer in action.
@sharwell Can you elaborate on your concern about value is { } x
being a code style change? It is syntactically as much of a null check as value is object
would be, but the same is not true of value is var x
.
I'm also concerned about encouraging the use of
value is var x
unless we _also_ have the ability to detect cases where the static type ofvalue
is a reference type, which means either nullable reference types is enabled or we have some other analyzer in action.
Are you talking about in not encouraging is var
in general? The proposed warning would only come into effect if the static type of value
is a non-nullable value type.
@YairHalberstadt
and consistency between patterns that declare a subvariable and those that don't.
This is a good point. Losing that consistency is the main thing I dislike about is object
, and I've seen others raise the same point.
x is {}
is a canonical null check. So is x is object
. On the false branch, the compiler knows that x
may be null (if null is in its domain). That is true even if the compiler already believed that x
could not be null to start with (e.g. a parameter declared string x
).
x is {} y
is not a canonical null check. Unless the compiler already believed x
could be null, the compiler will not infer that x
can be null in the false branch.
I forgot to say, I'd be happy with a CA* or IDE* warning too. The important part to me is that a warning is available by default in new projects for x is { }
and x is { } y
.
To strengthen the case for x is { } y
:
@333fred is that because
expr is { } i
will be pushed as the canonical null check when you want to introduce a non-null variable (either reference or value type)?
Yes.
https://github.com/dotnet/csharplang/issues/3369#issuecomment-619988890
If expr is { } y
will be considered the de facto null check when a non-nullable variable is needed, it should come with the same safety measures as expr is object
which have previously caused folks to recommend expr is object
over expr is { }
. (Namely, the warnings proposed at the top.)
Also, I've implemented these warnings and fixes at my day job and would be happy to contribute them.
The Ultimate C# Null-Checking Idiom would be e is not null and var x
for C# 9.0
@alrz No, that is way too long.
Oh, sounds like I can't be using patterns and being sarcastic at the same time.
Most helpful comment
Oh, sounds like I can't be using patterns and being sarcastic at the same time.