Resharper Gallery頁面
變化的歷史
該擴展的基本思想是改變Resmanter的靜態可取消性分析的行為,以便在不指定顯式[NotNull]或[CanBeNull]屬性的情況下獲得默認的無效註釋。例如,方法參數中的參考類型默認情況下是[NotNull] (→他們需要一個顯式[CanBeNull]才能變得無效)。

對於針對特定,可配置的,語法元素的啟用隱式刪除性,適用以下規則。
[NotNull] 。[CanBeNull]屬性覆蓋它們的無效性。null值的可選方法參數隱含[CanBeNull] 。簡而言之,上圖中顯示的代碼...
public string Bar ( string a , [ CanBeNull ] string b , string c = null )
{
// ...
}...隱式變成...
[ NotNull ]
public string Bar ( [ NotNull ] string a , [ CanBeNull ] string b , [ CanBeNull ] string c = null )
{
// ...
}[NotNull]默認情況下沒有此擴展,默認的可取消性值是“未知”,這意味著重音器將這些元素排除在其無效分析中。由於此擴展程序的默認可取[CanBeNull]的變化結果,我們必須僅針對特定代碼元素(例如參考類型參數作為參數作為參數將其傳遞為null ),並且不需要大多數情況的明確註釋(在大多數情況下(在代碼庫中)(試圖將傳遞null引用的代碼庫中的null引用降低至最小值))。
Resharper 9.2引入了對async ( Task<T>返回)方法的無效分析的支持。對於方法返回值的啟用隱式刪除性, Task<T>返回鍵入的方法也被隱式[ItemNotNull] (resharper使用此屬性來參考任務Task<T> )。對於無效的Task<T>返回值,可以用[ItemCanBeNull]覆蓋這一點。
以下示例程序在command.Equals("Hello")中包含一個潛在的NullReferenceException ,因為程序員錯過了GetCommand()也可以返回null 。
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 ] ;
}使用啟用的隱式無效性,該錯誤將通過Resharper的靜態分析檢測到。
GetCommand()中的null ,因為此方法將被隱式註釋為[NotNull] 。[CanBeNull]添加到GetCommand()來解決此警告。[CanBeNull]屬性,Resharper現在會警告Main()中的command.Equals("Hello")呼叫中的潛在NullReferenceException 。在上面的示例中,隱式刪除性迫使程序員在GetCommand()上修復缺失的[CanBeNull]屬性。這表明了代碼庫中的[CanBeNull]註釋的數量將如何增加,因此不僅可以改善ReSharper的靜態分析,還可以改善方法簽名的文檔(合同)。
該擴展程序的另一個目標是將Resharper的靜態分析與Fody Nullguard的隱式無效檢查同步。例如,此Fody Weaver注入throw new ArgumentNullException(/*...*/)語句使用與隱式nullability相同的規則進行方法。換句話說,這個編織者增加了運行時檢查,以確保RESARARAPER的靜態分析。
C#8將獲得無效的參考類型,將選項類型帶入C#語言。這與隱式無效性的語義相匹配,並且更進一步,因為它將其擴展到當地人,通用參數,因為無效註釋在類型級別上起作用。
[ CanBeNull ]
string Bar ( [ CanBeNull ] string a , string b )
{
string result = a ;
return result ;
}...然後對應於...
string ? Bar ( string ? a , string b )
{
string ? result = a ;
return result ;
}這將使將來不必要地進行隱式無效性,同時是一個完美的“升級路徑”,因為良好的[CanBeNull]被批准的代碼庫很容易移植到C#8。
自2016.1版本以來,RESHARPER支持(在“內部模式”中)具有以下差異的可比功能(請參閱代碼檢查|設置)。
隱式無效...
[NotNull]元素。 顯式或隱式[NotNull]元素類型用虛線的下劃線突出顯示。 (請參閱上面示例屏幕截圖中的Bar -method中的粉紅色下劃線。)這有助於識別所有[NotNull]元素,尤其是從基類和代碼元素中推斷的[NotNull]元素,這些元素和代碼元素被隱含地配置為[NotNull] 。
可以在“隱式無效”選項頁面上啟用/禁用突出顯示,並且可以在Visual Studio的“字體和顏色”選項中配置顏色。
對於代碼檢查中的特定語法元素,可以啟用或禁用隱式無效性|隱式無效選項頁面。

也可以使用AssemblyMetadataAttribute通過代碼配置隱式刪除性。這具有一個優點,即將配置編譯到程序集中,以便帶有安裝的隱式無用性的組件消費者獲得與庫解決方案中編譯的代碼元素相同的隱式無效註釋。
例子:
[ assembly : AssemblyMetadata ( "ImplicitNullability.AppliesTo" ,
"InputParameters, RefParameters, OutParametersAndResult, Fields, Properties" ) ]
[ assembly : AssemblyMetadata ( "ImplicitNullability.Fields" , "RestrictToReadonly" ) ]
[ assembly : AssemblyMetadata ( "ImplicitNullability.Properties" , "RestrictToGetterOnly" ) ]
[ assembly : AssemblyMetadata ( "ImplicitNullability.GeneratedCode" , "Exclude" ) ]除了無效分析的行為變化外,此擴展程序還提供了以下代碼檢查警告。
有關這些警告(及其動機)的更多信息,請參見其描述在“ Resmanper Code”檢查中|檢查嚴重性選項頁面。
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 )
{
} 非常感謝Fabian Schmied支持隱式無效性的設計和概念。