Resharper Gallery Seite
Geschichte der Veränderungen
Die grundlegende Idee dieser Erweiterung besteht darin, das Verhalten der statischen Nullabilitätsanalyse von Resharper so zu ändern, dass bestimmte Codeelemente eine Standard -Annotation für Nullbarkeit erhalten, ohne ein explizites [NotNull] oder [CanBeNull] -attribut anzugeben. Beispielsweise sind Referenztypen in Methodenparametern standardmäßig [NotNull] (→ Sie benötigen ein explizites [CanBeNull] , um nullbar zu werden).

Mit der aktivierten impliziten Nullabilität für spezifische, konfigurierbare Syntaxelemente gelten die folgenden Regeln.
[NotNull] .[CanBeNull] -attribut überschrieben werden.null -Standardwert sind implizit [CanBeNull] .Kurz gesagt, der Code wurde im obigen Bild angezeigt ...
public string Bar ( string a , [ CanBeNull ] string b , string c = null )
{
// ...
}... implizit wird ...
[ NotNull ]
public string Bar ( [ NotNull ] string a , [ CanBeNull ] string b , [ CanBeNull ] string c = null )
{
// ...
}[NotNull] standardmäßig Ohne diese Erweiterung ist der Standard -Nullability -Wert "unbekannt", was bedeutet, dass Resharper diese Elemente für seine Nullability -Analyse ausschließt. Infolge der geänderten Standardnullabilität dieser Erweiterung müssen wir [CanBeNull] -Notationen nur für bestimmte Codeelemente platzieren (z. B. ein Referenztypparameter, in dem er null als Argument übergeben sollte) und benötigen keine explizite Annotationen für die Mehrheit der Fälle (in Codebasen, die versuchen, das Bestehen von null -Referenzen auf ein Minimum zu reduzieren).
Resharper 9.2 Einführte Unterstützung für die Nullability -Analyse für async Methoden ( Task<T> return typed). Mit der aktivierten impliziten Nullabilität für Methodenrückgabewerte werden Task<T> typisierte Methoden auch implizit [ItemNotNull] (Resharper verwendet dieses Attribut, um auf den Wert der Task<T> zu verweisen). Für nullable Task<T> Rückgabewerte kann dies mit [ItemCanBeNull] überschrieben werden.
Das folgende Beispielprogramm enthält eine potenzielle NullReferenceException in command.Equals("Hello") da der Programmierer, dass GetCommand() auch null zurückgeben könnte.
public static void Main ( string [ ] args )
{
string command = GetCommand ( args ) ;
if ( command . Equals ( "Hello" ) )
Console . WriteLine ( "Hello World!" ) ;
}
private static string GetCommand ( string [ ] args )
{
if ( args . Length < 1 )
return null ;
return args [ 0 ] ;
}Mit der aktivierten impliziten Nullabilität wäre dieser Fehler durch die statische Analyse von Resharper festgestellt worden.
null in GetCommand() zurückzugeben, da diese Methode implizit als [NotNull] kommentiert würde.[CanBeNull] zu GetCommand() gelöst.[CanBeNull] -attributs war es nun Resharper vor dem potenziellen NullReferenceException im command.Equals("Hello") in Main() . Im obigen Beispiel zwingt die implizite Nullabilität den Programmierer, das fehlende [CanBeNull] -attribut auf GetCommand() zu beheben. Dies zeigt, wie die Anzahl der [CanBeNull] -Notationen in der Codebasis erhöht werden und daher die statische Analyse von Resharper nicht nur verbessert, sondern auch die Dokumentation von Methodensignaturen (Verträge).
Ein weiteres Ziel dieser Erweiterung ist es, die statische Analyse von Resharper synchron mit den impliziten Nullprüfungen von Fody Nullguard zu bringen. Zum Beispiel throw new ArgumentNullException(/*...*/) Anweisungen für Methodenparameter in Methodenkörper unter Verwendung derselben Regeln wie implizite Nullbarkeit . Mit anderen Worten, dieser Weber fügt Laufzeitüberprüfungen hinzu, um die statische Analyse von Resharper Nullability zu nähern.
C# 8 erhalten nullbare Referenztypen , die Optionstypen in die C# -Sprache einbringen. Dies entspricht der Semantik der impliziten Nullabilität und geht noch weiter aus, da sie die Einheimischen, generische Parameter, ... weil die Annotation der Nullbarkeit auf Typ -Ebene funktioniert.
[ CanBeNull ]
string Bar ( [ CanBeNull ] string a , string b )
{
string result = a ;
return result ;
}... dann entspricht ...
string ? Bar ( string ? a , string b )
{
string ? result = a ;
return result ;
} Dies wird in Zukunft und gleichzeitig einen perfekten "Upgrade -Pfad" unnötig machen, da eine gute [CanBeNull] -Antatierte Codebasis auf C# 8 leicht tragbar ist.
Seit Version 2016.1 unterstützt Resharper (im "internen Modus") eine vergleichbare Funktion (siehe Code -Inspektion | Einstellungen ) mit den folgenden Unterschieden.
Implizite Nullabilität ...
[NotNull] Elemente hinzu. Explizite oder implizite [NotNull] -Elementtypen werden mit einer gepunkteten Unterstreichung hervorgehoben. (Siehe die rosa Untersteuerung im Balken im Bar im obigen Beispiel -Screenshot.) Dies hilft, alle [NotNull] Elemente zu erkennen, insbesondere abgeleitete [NotNull] Elemente aus einer Basisklasse und Codeelementen, die als implizit [NotNull] konfiguriert sind.
Das Hervorheben kann auf der Seite der impliziten Nullability -Optionen aktiviert/deaktiviert werden, und die Farben können in den Optionen "Schriftarten und Farben" von Visual Studio konfiguriert werden.
Implizite Nullabilität kann für bestimmte Syntaxelemente in der Codeprüfung aktiviert oder deaktiviert werden | Seite implizite Nullability -Optionen.

Implizite Nullabilität kann auch mit einem Code unter Verwendung eines AssemblyMetadataAttribute konfiguriert werden. Dies hat den Vorteil, dass die Konfiguration in die Montage zusammengestellt wird, sodass die Verbraucher der Baugruppe mit installierten implizite Nullabilität dieselben implizite Nullabilitätsanmerkungen der kompilierten Codelemente wie innerhalb der Lösung der Bibliothek erhalten.
Beispiel:
[ assembly : AssemblyMetadata ( "ImplicitNullability.AppliesTo" ,
"InputParameters, RefParameters, OutParametersAndResult, Fields, Properties" ) ]
[ assembly : AssemblyMetadata ( "ImplicitNullability.Fields" , "RestrictToReadonly" ) ]
[ assembly : AssemblyMetadata ( "ImplicitNullability.Properties" , "RestrictToGetterOnly" ) ]
[ assembly : AssemblyMetadata ( "ImplicitNullability.GeneratedCode" , "Exclude" ) ]Zusätzlich zur Verhaltensänderung der Nullability -Analyse werden die folgenden Code -Inspektionswarnungen durch diese Erweiterung bereitgestellt.
Weitere Informationen zu diesen Warnungen (und ihrer Motivation) finden Sie in der Beschreibung in der Inspektion von Resharper Code | Seite der Schweregradoptionen für Inspektionen .
ID: ImplicitNotNullConflictInHierarchy
abstract class Base
{
public abstract void Method ( [ CanBeNull ] string a ) ;
}
class Derived : Base
{
// "Implicit NotNull conflicts with nullability in base type":
public override void Method ( string a )
{
}
} ID: ImplicitNotNullElementCannotOverrideCanBeNull
abstract class Base
{
[ CanBeNull ]
public abstract string Method ( ) ;
}
class Derived : Base
{
// "Implicit NotNull element cannot override CanBeNull in base type, nullability should be explicit":
public override string Method ( ) => "" ;
} IDs: ImplicitNotNullOverridesUnknownBaseMemberNullability resp. ImplicitNotNullResultOverridesUnknownBaseMemberNullability
class Derived : External . Class /* (external code with unannotated 'Method' and 'Function') */
{
// "Implicit NotNull overrides unknown nullability of base member, nullability should be explicit":
public override void Method ( string a )
{
}
// "Implicit NotNull result or out parameter overrides unknown nullability of base member,
// nullability should be explicit":
public override string Function ( ) => "" ;
} ID: NotNullOnImplicitCanBeNull
// "Implicit CanBeNull element has an explicit NotNull annotation":
void Foo ( [ NotNull ] int ? a )
{
} Vielen Dank an Fabian Schmied für die Unterstützung des Designs und der Konzeption implizite Nullabilität .