C# 如何按继承对类进行排序?

C# 如何按继承对类进行排序?,c#,linq,sorting,reflection,C#,Linq,Sorting,Reflection,我正在使用反射来检索可用类的列表,我希望将输入对象调整为最符合的特定的类;i、 e.我想做一些事情,比如: RawData input = new RawData() { ... }; Type targetAdapter = AdapterSelector.SelectAdapterFor(input); AdapterSelector.TryGetAdaptMethod(targetAdapter, out Func<RawData, Adapter> fAdapt); Adap

我正在使用反射来检索可用类的列表,我希望将输入对象调整为最符合的特定的类;i、 e.我想做一些事情,比如:

RawData input = new RawData() { ... };
Type targetAdapter = AdapterSelector.SelectAdapterFor(input);
AdapterSelector.TryGetAdaptMethod(targetAdapter, out Func<RawData, Adapter> fAdapt);
Adapter adapted = fAdapt(input);
使用reflection1可以按如下方式检索具有所需方法的类列表:

公共部分类适配器选择器
{
公共静态IEnumerable GetApplicatableAdapterTypes()
{
IEnumerable allTypes=typeof(AdapterSelector).Assembly.GetTypes();
IEnumerable ApplicatableTypes=所有类型中的t
其中,TryGetAdaptMethod(t,u)&&
TryGetMatchMethod(t,u3;)
选择t;
返回适用类型;
}
私有静态bool TryGetAdaptMethod(类型类型,输出函数自适应)
{
MethodInfo AdapterMethod=type.GetMethod(“Adapt”,BindingFlags.Static | BindingFlags.Public,null,新类型[]{typeof(RawData)},null);
if(adaptemethod!=null)
{
adapt=(Func)Delegate.CreateDelegate(typeof(Func),null,adapterMethod);
返回true;
}
其他的
{
adapt=null;
返回false;
}
}
私有静态bool TryGetMatchMethod(类型类型,out Func匹配)
{
MethodInfo matchMethod=type.GetMethod(“Match”,BindingFlags.Static | BindingFlags.Public,null,新类型[]{typeof(RawData)},null);
if(matchMethod!=null)
{
match=(Func)Delegate.CreateDelegate(typeof(Func),null,matchMethod);
返回true;
}
其他的
{
匹配=空;
返回false;
}
}
}
我假设我可以使用以下命令来订购此适配器列表:

public class TypeHierarchyComparer: IComparer<Type>
{
    public int Compare(Type lhs, Type rhs)
    {
        if (rhs.IsSubclassOf(lhs))
        {
            return -1;
        }
        else if (lhs.IsSubclassOf(rhs))
        {
            return +1;
        }
        else
        {
            // Return arbitrary but fixed value for siblings, cousins, etc.
            return lhs.FullName.CompareTo(rhs.FullName);
        }
    }
}
公共类TypeHierarchyComparer:IComparer
{
公共整数比较(lhs型、rhs型)
{
if(右侧发行类别(左侧))
{
返回-1;
}
否则如果(左侧发布类别(右侧))
{
返回+1;
}
其他的
{
//为兄弟姐妹、堂兄弟姐妹等返回任意但固定的值。
返回lhs.FullName.CompareTo(rhs.FullName);
}
}
}
请注意,这是一个偏序:如果一个类型是另一个类型的子类,则该类型应在后一个类型之后排序。如果两个类型都不是另一个的子类,则顺序未定义

通过这种排序,我希望以下适配器层次结构能够正确排序3:

  • 适配器
    • N
    • F
    • H
    • I
    • K
      • E
      • G
      • L
      • M
      • Q
      • R
    • O
    • B
    • C
    • J
    • P
      • AA
      • AB
      • D
      • S
      • T
然而,以下方面的结果:

AdapterSelector.GetApplicatableAdapterTypes().OrderBy((x)=>x,新类型HierarchyComparer())

它们是:

Adapter
AA
AB
B
C
D
N
F
I
J
K
p
E
E
G
L
M
S
T

顺序是否正确
O
p
应在
AA
之前、
AB
D
S
T
之前进行排序,
O
应在
B
C
J
之前进行排序。似乎子类是在其一个父类之后排序的,但不一定在其所有父类之后排序

如何按特定性对类进行排序?(即在所有子类的父类之前/之后排序)


1) 见、和

2) 我习惯于让匹配者在列表前面先申请


3) Visual Studio的解决方案资源管理器显示的类层次结构。我不能透露适配器的名称,因此我使用了
AA
T
,我保留了名称的字母顺序。

问题是您的任意排序规则太任意了

与其按类型名称排序(因此,比较
G
B
,可以说
G
应该排在
B
之后),不如找到两个不相关类型最接近的共同祖先。然后,您应该根据这两种类型的共同祖先的直接后代应用排序

因此,为了比较
G
B
,您可以找到最近的共同祖先(
Adapter
),然后找到这两种类型的后代类型(
K
B
),然后对这些类型执行任意排序规则


类似这样的内容(没有关于代码质量的承诺:-):

公共列表祖先(键入任意)
{
var result=新列表();
结果。添加(任何);
while(any!=typeof(object))
{
any=any.BaseType;
结果。插入(0,任何);
}
返回结果;
}
公共整数比较(lhs型、rhs型)
{
if(右侧发行类别(左侧))
{
返回-1;
}
否则如果(左侧发布类别(右侧))
{
返回+1;
}
其他的
{
var lAncs=祖先(lhs);
var rAncs=祖先(rhs);
int ix=0;
而(lAncs[ix]==Racs[ix])
{
我
public partial class AdapterSelector
{
    public static IEnumerable<Type> GetApplicableAdapterTypes()
    {
        IEnumerable<Type> allTypes = typeof(AdapterSelector).Assembly.GetTypes();
        IEnumerable<Type> applicableTypes = from t in allTypes
                                            where TryGetAdaptMethod(t, _) &&
                                                  TryGetMatchMethod(t, _)
                                            select t;
        return applicableTypes;
    }

    private static bool TryGetAdaptMethod(Type type, out Func<RawData, Adapter> adapt)
    {
        MethodInfo adaptMethod = type.GetMethod("Adapt", BindingFlags.Static|BindingFlags.Public, null, new Type[] { typeof(RawData) }, null);
        if (adaptMethod != null)
        {
            adapt = (Func<RawData, Adapter>)Delegate.CreateDelegate(typeof(Func<RawData, Adapter>), null, adapterMethod);
            return true;
        }
        else
        {
            adapt = null;
            return false;
        }
    }

    private static bool TryGetMatchMethod(Type type, out Func<RawData, bool> match)
    {
        MethodInfo matchMethod = type.GetMethod("Match", BindingFlags.Static|BindingFlags.Public, null, new Type[] { typeof(RawData) }, null);
        if (matchMethod != null)
        {
            match = (Func<RawData, bool>)Delegate.CreateDelegate(typeof(Func<RawData, bool>), null, matchMethod);
            return true;
        }
        else
        {
            match = null;
            return false;
        }
    }
}
public class TypeHierarchyComparer: IComparer<Type>
{
    public int Compare(Type lhs, Type rhs)
    {
        if (rhs.IsSubclassOf(lhs))
        {
            return -1;
        }
        else if (lhs.IsSubclassOf(rhs))
        {
            return +1;
        }
        else
        {
            // Return arbitrary but fixed value for siblings, cousins, etc.
            return lhs.FullName.CompareTo(rhs.FullName);
        }
    }
}
    public List<Type> Ancestors(Type any)
    {
        var result = new List<Type>();
        result.Add(any);
        while (any != typeof(object))
        {
            any = any.BaseType;
            result.Insert(0, any);
        }
        return result;
    }
    public int Compare(Type lhs, Type rhs)
    {
        if (rhs.IsSubclassOf(lhs))
        {
            return -1;
        }
        else if (lhs.IsSubclassOf(rhs))
        {
            return +1;
        }
        else
        {
            var lAncs = Ancestors(lhs);
            var rAncs = Ancestors(rhs);
            int ix = 0;
            while (lAncs[ix] == rAncs[ix])
            {
                ix++;
            }
            return lAncs[ix].FullName.CompareTo(rAncs[ix].FullName);
        }
    }