2015-06-08 9 views
20

मेरे पास निम्न कोड है जो मुझे बताएगा कि कोड में कहीं और एक निश्चित संपत्ति का उपयोग किया जाता है या नहीं। इसके पीछे विचार यह सत्यापित करना है कि private सेटर वाली संपत्ति को केवल पढ़ने के लिए बनाया जा सकता है या नहीं।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)) 

क्यों पर सच

है यह इस चेतावनी को दिखाता है? वंशजों की एक अज्ञात राशि है इसलिए लापता होने की अज्ञात राशि है। प्रत्येक पाश true, कि (जल्द से जल्द) 2 छोरों के बाद, दोनों मूल्यों true बन सकता है जिसका मतलब है कि करने के लिए hasStaticUsage या hasInstanceUsage सेट कर सकते हैं और अगर हालत विफल करना चाहिए: एक NAND रिटर्न true, true, true, false

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

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

केवल चर में से एक:

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

'isStaticProperty' कहाँ आरंभ नहीं हो जाता? –

+0

'hasInstanceUsage' के समान स्तर पर। मैं इसे पूर्णता के लिए शामिल करूंगा, लेकिन मुझे नहीं लगता कि इसका असर पड़ता है। –

+0

'मैं है निम्नलिखित कोड जो मुझे बता देगा या नहीं, एक निश्चित संपत्ति code' में कहीं प्रयोग किया जाता है - नहीं इस वी.एस. में एक देशी सुविधा है? – Davor

उत्तर

25

isStaticProperty पाश बाहर आरंभ नहीं हो जाता:

var isStaticProperty = propertySymbol.IsStatic; 

तो isStaticProperty गलत है, तो यह अभिव्यक्ति:

(isStaticConstructor && isStaticProperty) 

हमेशा गलत है, इसलिए hasStaticUsage गलत है।

तो isStaticProperty सच है, तो यह अभिव्यक्ति है:

(!isStaticConstructor && !isStaticProperty) 

हमेशा गलत है, इसलिए hasInstanceUsage गलत है।

किसी भी मामले में hasStaticUsage और hasInstanceUsage दोनों एक ही समय में सत्य नहीं हो सकते हैं।

10

यह ब्लॉक क्या तुमने कभी 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' के साथ कनेक्शन नहीं बनाया है और भूल गया है कि यह चक्र के दौरान नहीं बदल सका। –

संबंधित मुद्दे