C# 如何通过编程从一堆子类中找到最深的公共基类型?

C# 如何通过编程从一堆子类中找到最深的公共基类型?,c#,inheritance,reflection,subclass,C#,Inheritance,Reflection,Subclass,给定一组完全不同的对象,是否有可能找到它们共享的最特定的基类 例如,给定具有这些类层次结构的对象 object -> Vehicle -> WheeledVehicle -> Car -> SportsCar object -> Vehicle -> WheeledVehicle -> Bus object -> Vehicle -> WheeledVehicle -> MotorCycle object -> Vehicle -

给定一组完全不同的对象,是否有可能找到它们共享的最特定的基类

例如,给定具有这些类层次结构的对象

object -> Vehicle -> WheeledVehicle -> Car -> SportsCar
object -> Vehicle -> WheeledVehicle -> Bus
object -> Vehicle -> WheeledVehicle -> MotorCycle
object -> Vehicle -> WheeledVehicle -> Tricycle -> BigWheel
object -> Vehicle -> WheeledVehicle -> Tricycle -> Green Machine
(为了好玩。。。 )

是否可以使用此签名编写函数

public Type GetCommonBaseType(List<object> objects)
{
    ...
};
public类型GetCommonBaseType(列出对象)
{
...
};
…并让它返回“轮式车辆”

我的想法是以某种方式为每个对象建立继承链列表,反转它们,使它们都以“object”开头,然后遍历每个对象,检查所有列表中是否有匹配项。如果有任何项不匹配,那么前面的步骤就是最匹配的基本类型


然而,我不知道如何建立连锁店,因为“基地”是一个内部成员。这是可以使用反射来确定的吗?

可以使用反射来确定。让我们假设我们从
Type
实例开始,而不是从对象开始——这是更一般化的,您可以简单地将对象列表转换为它们的运行时类型列表,以涵盖您提到的用例

其思想是遍历每个输入类型的所有基类,并为每个输入类型增加一个“类型实例计数器”。完成此操作后,输入类型的所有公共基都必须使其计数器等于输入类型的数量。其中哪一个是最具衍生性的?简单地说,选择任何输入类型并开始遍历其类型层次结构,直到找到一个公共基;该类型是最派生的公共基

代码 我将使用此扩展方法:

public static IEnumerable<Type> TypeHierarchy(this Type type)
{
    do
    {
        yield return type;
        type = type.BaseType;
    } while (type != null);
}
更新 事后看来,很明显,构建计数类型字典也可以完全使用LINQ完成。因此,如果您喜欢compact,代码可以简化为:

public Type MostDerivedCommonBase(IEnumerable<Type> types)
{
    if (!types.Any()) return null;

    var counts = types.SelectMany(t => t.TypeHierarchy())
                      .GroupBy(t => t)
                      .ToDictionary(g => g.Key, g => g.Count());

    var total = counts[typeof(object)]; // optimization instead of types.Count()
    return types.First().TypeHierarchy().First(t => counts[t] == total);
}
公共类型MostDerivedCommonBase(IEnumerable类型)
{
如果(!types.Any())返回null;
var counts=types.SelectMany(t=>t.TypeHierarchy())
.GroupBy(t=>t)
.ToDictionary(g=>g.Key,g=>g.Count());
var total=counts[typeof(object)];//优化而不是类型。Count()
返回类型.First().TypeHierarchy().First(t=>counts[t]==total);
}

您可以使用
类型
对象来完成您正在谈论的工作。见MSDN:这是可以做到的。这并不简单,但我会花几分钟,试着写一个合理的算法。我是落选的选民。不过我把它改成了向上投票。我投了反对票,因为您的解决方案中没有代码,而且代码也不太简单,所以我觉得任何不包含工作代码的答案都是无用的。@evanmcdonnal:值得一提的是,我觉得投反对票是没有道理的,因为代码很短,完全遵循散文中描述的算法。但在任何情况下都不必担心。这可能是真的,但我确信,不通过一些示例理解它对许多程序员来说都是一种延伸。我并没有完全明白这一点,正计划采取一种完全不同的方法;递归检索父级,当集合中的每个类型都相同时返回,或当父级类型变为null时抛出。@evanmcdonnal:你说得对,我对其进行了编辑,以使描述更紧凑一些(主要是一致地使用“输入类型”)。有很多“类型”在那里,它不是那么清楚。
var types = new[] { typeof(MemoryStream), typeof(FileStream) };
Console.WriteLine(MostDerivedCommonBase(types)); // System.IO.Stream
public Type MostDerivedCommonBase(IEnumerable<Type> types)
{
    if (!types.Any()) return null;

    var counts = types.SelectMany(t => t.TypeHierarchy())
                      .GroupBy(t => t)
                      .ToDictionary(g => g.Key, g => g.Count());

    var total = counts[typeof(object)]; // optimization instead of types.Count()
    return types.First().TypeHierarchy().First(t => counts[t] == total);
}