private IEnumerable<Change> Compare(AssemblyDefinition source, AssemblyDefinition target) { var sourceTypes = GetPublicTypes(source); var targetTypes = GetPublicTypes(target); // First detect all new types in the newer assembly. var addedTypes = targetTypes.Except(sourceTypes, CecilComparer.TypeByFullName).ToList(); foreach (var addedType in addedTypes) yield return new TypeChange(ChangeType.TypeAdded, ChangeCategory.NonBreaking, CompatibilityLevel.Binary, addedType); targetTypes.RemoveAll(addedTypes); // Now detect all removed types in the newer assembly. var removedTypes = sourceTypes.Except(targetTypes, CecilComparer.TypeByFullName).ToList(); foreach (var removedType in removedTypes) yield return new TypeChange(ChangeType.TypeRemoved, ChangeCategory.Breaking, CompatibilityLevel.None, removedType); sourceTypes.RemoveAll(removedTypes); // We have now reduced the input to the types that occur in both assemblies, now we will need // to compare those one by one... foreach (var targetType in targetTypes) { var sourceType = sourceTypes.Single(t => CecilComparer.TypeByFullName.Equals(t, targetType)); TypeComparer comparer = new TypeComparer(); foreach (var change in comparer.Compare(sourceType, targetType)) yield return change; } }