Мне кажется, что самый простой способ идентифицировать эти циклы - это найти те, в которых отдел с зависимостью также в какой-то момент указан в качестве самой зависимости, и пройти через цепочку зависимостей между ними, чтобы увидеть, соединяются ли они.Тем не менее, ваша архитектура выглядит немного не так.Я бы создал объект для хранения отдела и его списка зависимостей, а также флаг того, есть ли у него циклические ссылки, подобные этому:
public class Department
{
public int Id { get; set; }
public string Name { get; set; }
public IList<int> Dependencies { get; set; }
public bool HasCircularReferences { get; set; }
}
Затем вы передаете список отделов и выполняете итерации.над каждым из них и найдите другие отделы, в которых этот отдел указан как зависимый.Затем вы возвращаетесь к ним через цепочку зависимостей, чтобы увидеть, вернетесь ли вы в текущий отдел.Вы можете использовать такой цикл (обратите внимание, что это статический метод, поскольку я тестировал его в консольном приложении):
private static void GetDependents(IList<int> dependencies, int seed)
{
foreach (var dependent in dependencies)
{
var dependentDept = departments.Where(d => d.Id == dependent).FirstOrDefault();
if (dependentDept.Dependencies.Count > 0)
{
if (dependencies.Contains(seed) || dependentDept.HasCircularReferences)
{
SetCircularReferenceFlag(seed, true);
break;
}
GetDependents(dependentDept.Dependencies, seed);
}
else
{
SetCircularReferenceFlag(seed, false);
break;
}
}
}
Это устанавливает флаг HasCircularReferences в отделе с использованием метода SetCircularReferenceFlag, который:
private static void SetCircularReferenceFlag(int departmentId, bool hasCircularReferences)
{
var seedDept = departments.Where(d => d.Id == departmentId).FirstOrDefault();
seedDept.HasCircularReferences = hasCircularReferences;
}
Затем метод GetDependents можно вызывать для каждого отдела в вашем списке следующим образом:
foreach (var department in departments)
{
GetDependents(department.Dependencies, department.Id);
}
Отделы были настроены так, чтобы использовать объект Department, определенный выше:
private static List<Department> departments = new List<Department>
{
new Department
{
Id = 1,
Name = "sales",
Dependencies = new List<int>{ 2 }
},
new Department
{
Id = 2,
Name = "accounts",
Dependencies = new List<int>{ 3 }
},
new Department
{
Id = 3,
Name = "marketing",
Dependencies = new List<int>{ 1 }
},
new Department
{
Id = 4,
Name = "finance",
Dependencies = new List<int>{ 1 }
}
};
При запуске через консольное приложение вы получаете следующие результаты: