C# 如何按继承对类进行排序?
我正在使用反射来检索可用类的列表,我希望将输入对象调整为最符合的特定的类;i、 e.我想做一些事情,比如: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
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
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);
}
}