【问题标题】:Order dependent types订单相关类型
【发布时间】:2013-01-28 15:29:09
【问题描述】:

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

例子:

public class Oil
{}

public class Seat
{}

public class Wheel : IDependOn<Oil>
{}

public class Car : IDependOn<Wheel>, IDependOn<Seat>
{}

所以,现在我想要一个函数(包括反射),它给我一个Dictionary&lt;Int32, Type&gt;,其中Int32 索引是顺序。

函数定义如下:

public Dictionary<Int32, Type> GetOrderedTypes(List<Type> types);

这个例子的结果应该是:

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

任务可能要复杂得多,但逻辑始终相同。

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

有人可以在这方面帮助我吗?

【问题讨论】:

标签: c#


【解决方案1】:

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

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();

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

【讨论】:

  • 所以,我测试了它,但如果我像这样对类型进行洗牌,它就不起作用: var orderedList = new[] { typeof(Car), typeof(Wheel), typeof(Oil),类型(座位)};
  • @ChristianNeuß:我的解决方案仅按依赖项排序。但是,我注意到您有一个附加要求,即没有依赖关系的类型应该放在第一位。我已更新我的答案,始终将这些类型放在首位。
猜你喜欢
  • 2015-05-29
  • 2020-01-10
  • 2012-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-05
  • 1970-01-01
  • 2012-02-22
相关资源
最近更新 更多