Я хотел бы рассчитать метрику TCC:
Tight Class Cohesion (TCC) измеряет отношение количества пар методов напрямую связанных видимых методов в классе NDC (C)и количество максимально возможных пар методов связей между видимыми методами класса NP (C).Два видимых метода напрямую связаны, если они обращаются к одним и тем же переменным экземпляра класса.n - количество видимых методов, ведущих к:
NP(C) = (n(n-1))/2
и
TCC(C) = NDC(C) / NP(C)
Итак, я написал метод, который анализирует все методы в классе, который я хочу проверить.Этот метод хранит все методы в этом классе, и их поля используются в словаре, который выглядит следующим образом:
Dictionary<MethodDefinition, IList<FieldReference>> references = new Dictionary<MethodDefinition, IList<FieldReference>>();
Итак, как теперь выполнить итерацию в этом словаре, чтобы проверить условие, упомянутое выше?Если я правильно понимаю, я должен найти эти две пары методов, которые используют один и тот же набор полей?Тогда как я могу сделать это наилучшим образом?Я думаю, что я должен перебрать словарь и посмотреть, содержит ли IList тот же набор?(даже не в том же порядке)?
Любые идеи oder`?
Мой код следующий, но он не работает правильно:
class TCC
{
public static int calculate(TypeDefinition type)
{
int count = 0;
Dictionary<MethodDefinition, HashSet<FieldReference>> references = new Dictionary<MethodDefinition, HashSet<FieldReference>>();
foreach (MethodDefinition method in type.Methods)
{
if (method.IsPublic)
{
references.Add(method, calculateReferences(method));
}
}
for (int i = 0; i < references.Keys.Count; i++)
{
HashSet<FieldReference> list = new HashSet<FieldReference>();
references.TryGetValue(references.Keys.ElementAt(i), out list);
if (isPair(references, list)) {
count++;
}
}
if (count > 0)
{
count = count / 2;
}
return count;
}
private static bool isPair(Dictionary<MethodDefinition, HashSet<FieldReference>> references, HashSet<FieldReference> compare)
{
for (int j = 0; j < references.Keys.Count; j++)
{
HashSet<FieldReference> compareList = new HashSet<FieldReference>();
references.TryGetValue(references.Keys.ElementAt(j), out compareList);
for (int i = 0; i < compare.Count; i++)
{
if (containsAllElements(compareList, compare)) {
return true;
}
}
}
return false;
}
private static bool containsAllElements(HashSet<FieldReference> compareList, HashSet<FieldReference> compare)
{
for (int i = 0; i < compare.Count; i++)
{
if (!compareList.Contains(compare.ElementAt(i)))
{
return false;
}
}
return true;
}
private static HashSet<FieldReference> calculateReferences(MethodDefinition method)
{
HashSet<FieldReference> references = new HashSet<FieldReference>();
foreach (Instruction instruction in method.Body.Instructions)
{
if (instruction.OpCode == OpCodes.Ldfld)
{
FieldReference field = instruction.Operand as FieldReference;
if (field != null)
{
references.Add(field);
}
}
}
return references;
}
}