我有一个创造性的问题。我想给类型一个依赖于依赖的订单。 :)
示例:
public class Oil
{}
public class Seat
{}
public class Wheel : IDependOn<Oil>
{}
public class Car : IDependOn<Wheel>, IDependOn<Seat>
{}
所以,现在我想要有一个函数(包括反射)给我一个Dictionary<Int32, Type>
,其中Int32
索引是订单。
函数定义如下:
public Dictionary<Int32, Type> GetOrderedTypes(List<Type> types);
此示例的结果应为:
<1, Oil>
<2, Seat>
<3, Wheel>
<4, Car>
任务可能要复杂得多,但也会有相同的逻辑。
在这方面,有人可以帮助我吗?
答案 0 :(得分:3)
以下是您问题的解决方案:
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();
如果你想要一个带索引作为键的字典,你可以从有序列表中轻松创建它。