2015-06-08 23 views
20

我有以下代碼,它會告訴我某個屬性是否在代碼的其他地方使用。這背後的想法是驗證是否只能使用private設置者進行只讀屬性。爲什麼ReSharper告訴我這個表達總是對的?

這裏有幾個陷阱,但主要的是對構造函數外的屬性賦值意味着它不會觸發。此外,靜態屬性可能只有在靜態構造函數中才能觸發診斷。同樣,一個實例屬性只需要一個實例構造函數。

現在,我到目前爲止的大多數場景都被佔了,但ReSharper在這段代碼中給了我一個警告,我似乎無法弄清楚它的邏輯。上述規範在此位的代碼翻譯:

var isStaticProperty = propertySymbol.IsStatic; 
bool hasInstanceUsage = false; 
bool hasStaticUsage = false; 

foreach (var identifier in outerClass.DescendantNodes().OfType<IdentifierNameSyntax>()) 
{ 
    var memberSymbol = context.SemanticModel.GetSymbolInfo(identifier); 
    if (memberSymbol.Symbol.Equals(propertySymbol)) 
    { 
     var constructor = identifier.Ancestors().OfType<ConstructorDeclarationSyntax>() 
               .FirstOrDefault(); 
     var isInConstructor = constructor != null; 
     var isAssignmentExpression = identifier.Ancestors() 
               .OfType<AssignmentExpressionSyntax>() 
               .FirstOrDefault() != null; 

     // Skip anything that isn't a setter 
     if (!isAssignmentExpression) 
     { 
      continue; 
     } 

     // if it is a setter but outside the constructor, we don't report any diagnostic 
     if (!isInConstructor) 
     { 
      return; 
     } 

     var isStaticConstructor = context.SemanticModel 
             .GetDeclaredSymbol(constructor).IsStatic; 
     if (isStaticConstructor && isStaticProperty) 
     { 
      hasStaticUsage = true; 
     } 

     if (!isStaticConstructor && !isStaticProperty) 
     { 
      hasInstanceUsage = true; 
     } 
    } 
} 

// We can't set it to readonly if it's set in both the instance 
// and the static constructor 
// We need a NAND operation: either it's never set, 
// it's set in ctor 1 or it's set in ctor 2 
if (!(hasStaticUsage & hasInstanceUsage)) 
{ 
    context.ReportDiagnostic(Diagnostic.Create(
       Rule, property.Identifier.GetLocation(), propertySymbol.Name)); 
} 

與警告是

表達始終是真實的

上線

if (!(hasStaticUsage & hasInstanceUsage)) 

爲什麼它顯示這個警告?有一個未知數量的後代,所以有一個未知量的循環。每個環可以設置hasStaticUsagehasInstanceUsagetrue,這意味着後2個循環(在最早),這兩個值可以成爲true和如果條件應失敗:一個NAND返回truetruetruefalse

這是布爾邏輯,我打算做到:

+----------------+------------------+--------+ 
| hasStaticUsage | hasInstanceUsage | result | 
+----------------+------------------+--------+ 
| false   | false   | true | 
| false   | true    | true | 
| true   | false   | true | 
| true   | true    | false | 
+----------------+------------------+--------+ 
+0

凡'isStaticProperty'初始化? –

+0

在'hasInstanceUsage'的同一級別。爲了完整起見,我會將其納入其中,但我認爲它沒有影響。 –

+0

'我有以下代碼會告訴我某個屬性是否在代碼的其他地方使用 - - 這不是VS中的本地特性嗎? – Davor

回答

25

isStaticProperty初始化外循環:

var isStaticProperty = propertySymbol.IsStatic; 

如果isStaticProperty爲假,則此表達式:

(isStaticConstructor && isStaticProperty) 

總是假,因此hasStaticUsage是假的。

如果isStaticProperty是真的,那麼這個表達式:

(!isStaticConstructor && !isStaticProperty) 

永遠是假的,因此hasInstanceUsage是假的。

在任何情況下hasStaticUsagehasInstanceUsage不能同時爲真。

10

此塊就不可能,你將永遠這兩個變量的設置爲true

if (isStaticConstructor && isStaticProperty) 
{ 
    hasStaticUsage = true; 
} 

if (!isStaticConstructor && !isStaticProperty) 
{ 
    hasInstanceUsage = true; 
} 

的變量只有一個可以設置爲true。所以你的if聲明將永遠等於!false == true

+0

警告仍然存在。 –

+0

@JeroenVannevel請參閱我的編輯。代碼中的其他地方存在邏輯問題。 –

+0

原來這確實是因爲'isStaticProperty'布爾值,我完全忽略了它。我感謝你和我一起尋找。 –

14

你可以找到通過這個表達式建立真值表答案。 isStaticConstructor && isStaticProperty!isStaticConstructor && !isStaticProperty。我們一起做吧。

isStaticConstructor & & isStaticProperty

+---------------------+------------------+--------+ 
| isStaticConstructor | isStaticProperty | result | 
+---------------------+------------------+--------+ 
| false    | false   | false | 
| false    | true    | false | 
| true    | false   | false | 
| true    | true    | true | 
+---------------------+------------------+--------+ 

!isStaticConstructor & &!isStaticProperty

+---------------------+------------------+--------+ 
| isStaticConstructor | isStaticProperty | result | 
+---------------------+------------------+--------+ 
| false    | false   | true | 
| false    | true    | false | 
| true    | false   | false | 
| true    | true    | false | 
+---------------------+------------------+--------+ 

所以你可以看到,沒有任何可能性都isStaticConstructor && isStaticProperty!isStaticConstructor && !isStaticPropertytrue

因此,根據您提供的真值表,!(hasStaticUsage & hasInstanceUsage)變爲false的唯一可能性是兩個表達式在同一時間內都是true,這是不可能的。

+0

這的確是原因 - 我只是沒有任何跟'isStaticProperty'連接,忘了,它不能週期期間改變。 –

相關問題