Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 顺序相关类型_C# - Fatal编程技术网

C# 顺序相关类型

C# 顺序相关类型,c#,C#,我有一个创造性的问题。我想给类型一个依赖于依赖项的顺序。:) 例如: public class Oil {} public class Seat {} public class Wheel : IDependOn<Oil> {} public class Car : IDependOn<Wheel>, IDependOn<Seat> {} 此示例的结果应为: <1, Oil> <2, Seat> <3, Wheel>

我有一个创造性的问题。我想给类型一个依赖于依赖项的顺序。:)

例如:

public class Oil
{}

public class Seat
{}

public class Wheel : IDependOn<Oil>
{}

public class Car : IDependOn<Wheel>, IDependOn<Seat>
{}
此示例的结果应为:

<1, Oil>
<2, Seat>
<3, Wheel>
<4, Car>

这些任务可能要复杂得多,但逻辑将永远相同

  • 没有依赖项的类型的顺序最低
  • 对于具有相同依赖项的类型,顺序并不重要

在这方面有人能帮我吗?

以下是解决您问题的方法:

interface IDependOn<T> { }

class Oil { }

class Seat { }

class Wheel : IDependOn<Oil> { }

class Car : IDependOn<Wheel>, IDependOn<Oil> { }

static class TypeExtensions {

  public static IEnumerable<Type> OrderByDependencies(this IEnumerable<Type> types) {
    if (types == null)
      throw new ArgumentNullException("types");
    var dictionary = types.ToDictionary(t => t, t => GetDependOnTypes(t));
    var list = dictionary
      .Where(kvp => !kvp.Value.Any())
      .Select(kvp => kvp.Key)
      .ToList();
    foreach (var type in list)
      dictionary.Remove(type);
    foreach (var keyValuePair in dictionary.Where(kvp => !kvp.Value.Any())) {
      list.Add(keyValuePair.Key);
      dictionary.Remove(keyValuePair.Key);
    }
    while (dictionary.Count > 0) {
      var type = dictionary.Keys.First();
      Recurse(type, dictionary, list);
    }
    return list;
  }

  static void Recurse(Type type, Dictionary<Type, IEnumerable<Type>> dictionary, List<Type> list) {
    if (!dictionary.ContainsKey(type))
      return;
    foreach (var dependOnType in dictionary[type])
      Recurse(dependOnType, dictionary, list);
    list.Add(type);
    dictionary.Remove(type);
  }

  static IEnumerable<Type> GetDependOnTypes(Type type) {
    return type
      .GetInterfaces()
      .Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDependOn<>))
      .Select(i => i.GetGenericArguments().First());
  }

}

如果您想要索引作为键的字典,可以从有序列表轻松创建它。

要开始,请尝试搜索“拓扑排序”。为什么要使用字典而不是列表?的可能副本是拓扑排序的一个很好的介绍。代码是JavaScript,但翻译成c#并不难。因此,我测试了它,但如果我像这样洗牌类型,它就不起作用了:var orderedList=new[]{typeof(Car)、typeof(Wheel)、typeof(Oil)、typeof(Seat)}@克里斯蒂安:我的解决方案只按依赖项排序。然而,我已经注意到,您有一个额外的要求,即不依赖的类型应该放在第一位。我已经更新了我的答案,总是把这些类型放在第一位。
interface IDependOn<T> { }

class Oil { }

class Seat { }

class Wheel : IDependOn<Oil> { }

class Car : IDependOn<Wheel>, IDependOn<Oil> { }

static class TypeExtensions {

  public static IEnumerable<Type> OrderByDependencies(this IEnumerable<Type> types) {
    if (types == null)
      throw new ArgumentNullException("types");
    var dictionary = types.ToDictionary(t => t, t => GetDependOnTypes(t));
    var list = dictionary
      .Where(kvp => !kvp.Value.Any())
      .Select(kvp => kvp.Key)
      .ToList();
    foreach (var type in list)
      dictionary.Remove(type);
    foreach (var keyValuePair in dictionary.Where(kvp => !kvp.Value.Any())) {
      list.Add(keyValuePair.Key);
      dictionary.Remove(keyValuePair.Key);
    }
    while (dictionary.Count > 0) {
      var type = dictionary.Keys.First();
      Recurse(type, dictionary, list);
    }
    return list;
  }

  static void Recurse(Type type, Dictionary<Type, IEnumerable<Type>> dictionary, List<Type> list) {
    if (!dictionary.ContainsKey(type))
      return;
    foreach (var dependOnType in dictionary[type])
      Recurse(dependOnType, dictionary, list);
    list.Add(type);
    dictionary.Remove(type);
  }

  static IEnumerable<Type> GetDependOnTypes(Type type) {
    return type
      .GetInterfaces()
      .Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDependOn<>))
      .Select(i => i.GetGenericArguments().First());
  }

}
var orderedList =
  new[] { typeof(Oil), typeof(Seat), typeof(Wheel), typeof(Car) }
    .OrderByDependencies();