У меня есть следующий код, который скажет мне, используется ли какое-либо свойство в другом месте кода. Идея этого заключается в том, чтобы проверить, может ли свойство с установщиком 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 set in both the instance
// and the static constructor
// We need a NAND operation: either it never set,
// it set in ctor 1 or it set in ctor 2
if (!(hasStaticUsage & hasInstanceUsage))
{
context.ReportDiagnostic(Diagnostic.Create(
Rule, property.Identifier.GetLocation(), propertySymbol.Name));
}
При наличии предупреждения
Выражение всегда истинно
на линии
if (!(hasStaticUsage & hasInstanceUsage))
Почему это предупреждение? Есть неизвестное количество потомков, так что неизвестное количество петель. Каждый цикл может установить hasStaticUsage
или hasInstanceUsage
в true
, что означает, что после двух циклов (как можно раньше) оба значения могут стать true
, а условие if должно завершиться неудачно: NAND возвращает true
, true
, true
, false
.
Это логическая логика, которую я намереваюсь выполнить:
+----------------+------------------+--------+
| hasStaticUsage | hasInstanceUsage | result |
+----------------+------------------+--------+
| false | false | true |
| false | true | true |
| true | false | true |
| true | true | false |
+----------------+------------------+--------+