Three lines of code and I already have warnings:
var serializer = new XmlSerializer(typeof(Files));
using var fs = new FileStream(@"Files.xml", FileMode.Open, FileAccess.Read, FileShare.Read);
var files = (Files)serializer.Deserialize(fs);
serializer
and fs
are obviously not null to any kind of static code analyzer. I haven't done anything to or with files
yet.
And yet on the assignment I get compiler warning CS8600: Converting null literal or possible null value to non-nullable type
'serializer' is not null here.
Erm, what are you trying to say?
The solution apparently is to write the last line like this:
var files = (Files)serializer.Deserialize(fs)!;
But I have no clue what I've accomplished with that besides getting rid of the compiler warning or how it supposedly improves my code in any way.
CodePudding user response:
The solution apparently is to write the last line like this:
Your solution is wrong, the warning is because XmlSerializer.Deserialize
may return null. Now you want to cast a possible null value object?
to a non-nullable type Files
, but you cannot guarantee that the deserialization always succeed. So the correct way to suppress this warning is:
var files = (Files?)serializer.Deserialize(fs);
CodePudding user response:
It's not for the compiler to work out what will be the case at run time. Doing so might be easy or it might be hard or it might be impossible. It's not going to try. If you call a method that CAN return null
then you cannot assign its result to a variable that can NOT be null
.
Using the !
operator is something like a cast. When you cast, you're telling the compiler that you are taking responsibility for ensuring that a reference that could, in theory, be to an object of various types will, in fact, be to an object of a specific type at run time. The !
is, similarly, telling the compiler that you are taking responsibility for ensuring that a reference that could, in theory, be null
will not, in fact, be null
at run time. If you don't fulfil that responsibility then an exception may be thrown at run time, just as it would if your specified cast failed.