在 C# 中,如何获得 class 到基 class 的继承距离?
In C#, how could I get a class's inheritance distance to base class?
例如:
我有以下 classes:
public class A {}
public class B:A {}
public class C:B {}
public class D:C {}
如果有一个方便的方法,比如获取到基的层级距离class(而不是测试D.IsSubclassOf(B))来确定D更接近A,还是B更接近离A更近?
也许这对您有帮助:
public static int? GetDegreeOfRelationship(Type typeA, Type typeB)
{
if (typeA.IsInterface || typeB.IsInterface) return null; // interfaces are not part of the inheritance tree
if (typeA == typeB) return 0;
int distance = 0;
Type child;
if (typeA.IsAssignableFrom(typeB))
{
child = typeB;
while ((child = child.BaseType) != typeA)
distance--;
return --distance;
}
else if(typeB.IsAssignableFrom(typeA))
{
child = typeA;
while ((child = child.BaseType) != typeB)
distance++;
return ++distance;
}
else
return null;
}
用法:
int? distance = GetDegreeOfRelationship(typeof(A), typeof(D)); // -3
int? distance = GetDegreeOfRelationship(typeof(D), typeof(A)); // 3
int? distance = GetDegreeOfRelationship(typeof(B), typeof(B)); // 0
int? distance = GetDegreeOfRelationship(typeof(D), typeof(string)); // null
我已经截取了@kha 建议的代码并根据这个答案为您进行了改编:Get inheritance tree of type
public static class TypeExtensions
{
public static IEnumerable<Type> GetInheritancHierarchy
(this Type type)
{
for (var current = type; current != null; current = current.BaseType)
yield return current;
}
public static int GetInheritanceDistance<TOther>(this Type type)
{
return type.GetInheritancHierarchy().TakeWhile(t => t != typeof(TOther)).Count();
}
}
用法
var c = new C(); // 2
Console.WriteLine(c.GetType().GetInheritanceDistance<A>());
var b = new B(); // 1
Console.WriteLine(b.GetType().GetInheritanceDistance<A>());
您可以使用扩展方法来扩展 Type
的行为以遍历层次结构以得出到基地的距离或到基地的路径:
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
System.Windows.Forms.Form a = new System.Windows.Forms.Form();
Console.WriteLine(a.GetType().DistanceToBase());
Console.WriteLine(a.GetType().PathToBase());
}
}
public static class Extensions
{
public static int DistanceToBase(this Type ob)
{
if (ob.BaseType == null)
{
return 0;
}
else return 1 + ob.BaseType.DistanceToBase();
}
public static string PathToBase(this Type ob)
{
if (ob.BaseType == null)
{
return ob.Name;
}
return ob.Name + "->" + ob.BaseType.PathToBase();
}
}
例如: 我有以下 classes:
public class A {}
public class B:A {}
public class C:B {}
public class D:C {}
如果有一个方便的方法,比如获取到基的层级距离class(而不是测试D.IsSubclassOf(B))来确定D更接近A,还是B更接近离A更近?
也许这对您有帮助:
public static int? GetDegreeOfRelationship(Type typeA, Type typeB)
{
if (typeA.IsInterface || typeB.IsInterface) return null; // interfaces are not part of the inheritance tree
if (typeA == typeB) return 0;
int distance = 0;
Type child;
if (typeA.IsAssignableFrom(typeB))
{
child = typeB;
while ((child = child.BaseType) != typeA)
distance--;
return --distance;
}
else if(typeB.IsAssignableFrom(typeA))
{
child = typeA;
while ((child = child.BaseType) != typeB)
distance++;
return ++distance;
}
else
return null;
}
用法:
int? distance = GetDegreeOfRelationship(typeof(A), typeof(D)); // -3
int? distance = GetDegreeOfRelationship(typeof(D), typeof(A)); // 3
int? distance = GetDegreeOfRelationship(typeof(B), typeof(B)); // 0
int? distance = GetDegreeOfRelationship(typeof(D), typeof(string)); // null
我已经截取了@kha 建议的代码并根据这个答案为您进行了改编:Get inheritance tree of type
public static class TypeExtensions
{
public static IEnumerable<Type> GetInheritancHierarchy
(this Type type)
{
for (var current = type; current != null; current = current.BaseType)
yield return current;
}
public static int GetInheritanceDistance<TOther>(this Type type)
{
return type.GetInheritancHierarchy().TakeWhile(t => t != typeof(TOther)).Count();
}
}
用法
var c = new C(); // 2
Console.WriteLine(c.GetType().GetInheritanceDistance<A>());
var b = new B(); // 1
Console.WriteLine(b.GetType().GetInheritanceDistance<A>());
您可以使用扩展方法来扩展 Type
的行为以遍历层次结构以得出到基地的距离或到基地的路径:
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
System.Windows.Forms.Form a = new System.Windows.Forms.Form();
Console.WriteLine(a.GetType().DistanceToBase());
Console.WriteLine(a.GetType().PathToBase());
}
}
public static class Extensions
{
public static int DistanceToBase(this Type ob)
{
if (ob.BaseType == null)
{
return 0;
}
else return 1 + ob.BaseType.DistanceToBase();
}
public static string PathToBase(this Type ob)
{
if (ob.BaseType == null)
{
return ob.Name;
}
return ob.Name + "->" + ob.BaseType.PathToBase();
}
}