top of page

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.

0 kommentarer
bottom of page