Ho il seguente codice che mi dirà se una certa proprietà è usata o meno nel codice. L'idea alla base di questo è verificare se una proprietà con un setter private
può essere effettuata in sola lettura.Perché ReSharper mi dice che questa espressione è sempre vera?
Qui ci sono diversi trucchi, ma i più importanti sono che un'assegnazione alla proprietà al di fuori del costruttore significa che non sparerà. Inoltre, una proprietà statica può avere solo un'assegnazione in un costruttore statico per attivare la diagnostica. Allo stesso modo, una proprietà di istanza richiede solo un costruttore di istanze.
Ora, la maggior parte degli scenari che ho finora sono spiegati, ma ReSharper mi dà un avvertimento in questo pezzo di codice e non riesco a capire la sua logica. La specifica di cui sopra è tradotto in questa porzione di codice:
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));
}
Con l'avvertimento essendo
espressione è sempre vero
sulla linea
if (!(hasStaticUsage & hasInstanceUsage))
Perché mostra questo avvertimento? Ci sono una quantità sconosciuta di discendenti quindi c'è una quantità sconosciuta di loop. Ogni loop può impostare hasStaticUsage
o hasInstanceUsage
a true
, il che significa che dopo 2 cicli (al più presto), entrambi i valori potrebbero diventare true
e se condizione dovrebbe sicuro: un NAND restituisce true
, true
, true
, false
.
Questa è la logica booleana ho intenzione di compiere:
+----------------+------------------+--------+
| hasStaticUsage | hasInstanceUsage | result |
+----------------+------------------+--------+
| false | false | true |
| false | true | true |
| true | false | true |
| true | true | false |
+----------------+------------------+--------+
Dove è inizializzato 'isStaticProperty'? –
Allo stesso livello di 'hasInstanceUsage'. Lo includerò per completezza, ma non penso che abbia un impatto. –
'Ho il seguente codice che mi dirà se una certa proprietà è usata o meno altrove nel codice' - non è questa una caratteristica nativa in VS? – Davor