Utforska nya non-nullable-varningarna i C# 8
Edument

Utforska nya non-nullable-varningarna i C# 8

​C# 8 ger oss många nya spännande features, och min personliga favorit är den om non-nullable-typer.

Om du inte känner till denna feature, rekommenderar jag att du först läser följande:

När jag gick igenom vad som skrivits om denna nya feature på nätet, upptäckte jag att de flesta exemplen såg ut ungefär så här: 

private static string DoMagicStuff(string? input)
{  
 if (input.Length > 0)  //Dereference of a possibly null reference        return input.ToUpper().Trim();
   else
        return null; //Possible null reference return
} 

Det är naturligtvis coolt, men vad för andra varningar kan Roslyn-kompilatorn åstadkomma? I vilken grad kan kompilatorn upptäcka null-varningar? Jag ville att denna blogpost skulle handla om så många som möjligt av de null-relaterade varningarna.

Så, för att få en bättre känsla för vad som verkligen är möjligt, häng med när jag experimenterar!

Var hittar vi alla möjliga kompilatorvarningarna?

Första steget är att kolla på alla relaterade nullvarningar som existerar, och utifrån det få en bättre idé om vad som är möjligt.

Under mina undersökningar insåg jag att källkoden till Roslyns egen kompilator är den bästa källan till information. Källkoden för Roslyn ligger på GitHub här. I källkoden hittade jag ErrorCode enum:en här. Den innehåller en stor enum med alla möjliga felmeddelanden och bekvämt nog låg alla nullrelaterade varningar mellan 8597 ->8715. 

Ett exempel på denna enum är:

internal enum ErrorCode
{    
     // ...    
     WRN_ThrowPossibleNull = 8597,    
     ERR_IllegalSuppression = 8598,    
     WRN_ConvertingNullableToNonNullable = 8600,    
     WRN_NullReferenceAssignment = 8601,    
     WRN_NullReferenceReceiver = 8602,    
     WRN_NullReferenceReturn = 8603,    
     WRN_NullReferenceArgument = 8604,   
     WRN_UnboxPossibleNull = 8605,    
     WRN_NullReferenceIterationVariable = 8606,    
     WRN_DisallowNullAttributeForbidsMaybeNullAssignment = 8607,    
     WRN_NullabilityMismatchInTypeOnOverride = 8608,    // ...
}

Varningssträngarna

Det här är en bra början, men att bara ha varningsnumret och namnet är kanske inte till så stor hjälp. Jag vill ju se de riktiga varningssträngarna, var hittar jag dem?

Det visar sig att jag för varje given varning här ovanför, baserat på enum-namnet, kan kolla upp motsvarande varningsmeddelandesträng i filen CSharpResources.resx , som ligger här. Till exempel, för varningen WRN_NullReferenceReturn , är motsvarande varningssträng: 

<data name="WRN_NullReferenceReturn" xml:space="preserve">
    <value>Possible null reference return.</value>
  </data>

Coolt! Jag har hittat alla nullrelaterade varningsmeddelanden i kompilatorns källkod, men nu är frågan: Hur skriver jag C#8-kod för att trigga huvuddelen av de här varningarna? 

Varningarna

Varningarna som jag skapat testkod för är följande:

Exceptions
CS8597         Thrown value may be null.  

Partial classes
CS8611         Nullability of reference types in type of parameter 'XXX' doesn't match partial method declaration.  

Delegates
CS8621         Nullability of reference types in return type of 'XXX' doesn't match the target delegate 'YYY'.  
CS8622         Nullability of reference types in type of parameter 'XXX' of 'YYY' doesn't match the target delegate 'ZZZ'.  

Inheritance 
CS8609         Nullability of reference types in return type doesn't match overridden member.  
CS8610         Nullability of reference types in type of parameter 'XXX' doesn't match overridden member.  

Interface  
CS8613         Nullability of reference types in return type of 'XXXX' doesn't match implicitly implemented member 'YYY'.  
CS8614         Nullability of reference types in type of parameter 'XX' of 'YYY' doesn't match implicitly implemented member 'ZZZ'.  
CS8616         Nullability of reference types in return type doesn't match implemented member 'XXX'.  
CS8617         Nullability of reference types in type of parameter 'XXX' doesn't match implemented member 'YYY'.  

Field and properties
CS8618         Non-nullable property 'XXX' is uninitialized.   CS8618         Non-nullable field 'XXX' is uninitialized.  

Methods calls
CS8603         Possible null reference return.  
CS8604         Possible null reference argument for parameter 'XXXX' in 'YYYY'.
CS8620         Argument of type 'XXX' cannot be used for parameter 'YYY' of type 'ZZZ' in 'AAA' due to differences in the nullability of reference types.  
CS8624         Argument of type 'XXX' cannot be used as an output of type 'YYY' for parameter 'ZZZ' in 'AAA' due to differences in the nullability of reference types.  

Assignments
CS8600         Converting null literal or possible null value to non-nullable type.
CS8601         Possible null reference assignment.
CS8602         Dereference of a possibly null reference.
CS8605         Unboxing a possibly null value.  
CS8606         Possible null reference assignment to iteration variable
CS8619         Nullability of reference types in value of type 'XXX' doesn't match target type 'YYY'.  
CS8625         Cannot convert null literal to non-nullable reference type.
CS8629         Nullable value type may be null.

Generics
CS8631         The type '{3}' cannot be used as type parameter '{2}' in the generic type or method '{0}'. Nullability of type argument '{3}' doesn't match constraint type '{1}'.</value>
CS8634         The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match 'class' constraint.

Majoriteten av problemen relaterade till non-nullable-typer representeras som varningar, men det finns också några som hanteras som rena kompileringsfel. Jag bestämde mig för att ignorera dem här, eftersom jag föredrar att min kod faktiskt kompilerar.

Källkoden

Källkoden för projektet som triggar alla varningarna ovan hittar du på GitHub här. 

Slutsats

Det är verkligen imponerande hur många varningar relaterade till null som kompilatorn kan generera, och jag antar att listan kommer att växa över tiden i takt med att kompilatorn och denna feature utvecklas.     

Feedback önskas

Har du hittat någon kod som täcker in en nullrelaterad varning som jag inte nämnt? Kontakta mig via tore@edument.se eller skicka en pull request!

Om författaren

På Edument arbetar Tore Nestenius med att utbilda programmerare och delar gärna med mig av erfarenheter från tidigare projekt. Han har även en roll som ”Code Buddy” åt Eduments kunder runt om i världen där han coachar utvecklingsteam i arkitekturfrågor och säkerhet.

Tore är nyfiken på nya tekniker och lever efter mottot ”Man kan inget förrän man kan förklara det för andra”.

Vill du lära dig mer om C# och .NET core? Ta då en titt på kurserna vi på Edument erbjuder, vi har kurser för allt från nybörjare till avancerade utvecklare inom C#/.NET. Se våra kurser inom .NET. 

JavaScript seem to be disabled in your browser.

You must have JavaScript enabled in your browser to utilize the functionality of this website.