ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – 如何以编程方式从一堆子类中找到最深入的公共基类型?

2019-05-20 09:03:47  阅读:162  来源: 互联网

标签:c reflection inheritance subclass


给定一组不同的对象,是否有可能找到他们共享的最具体的基类?

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

object -> Vehicle -> WheeledVehicle -> Car -> SportsCar
object -> Vehicle -> WheeledVehicle -> Bus
object -> Vehicle -> WheeledVehicle -> MotorCycle
object -> Vehicle -> WheeledVehicle -> Tricycle -> BigWheel
object -> Vehicle -> WheeledVehicle -> Tricycle -> Green Machine

(为了娱乐…
http://www.wired.com/autopia/2011/03/green-machine-bike-is-a-big-wheel-for-grownups)

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

public Type GetCommonBaseType(List<object> objects)
{
    ...
};

…让它返回’WheeledVehicle’?

我的想法是以某种方式为每个对象构建继承链列表,反转它们以便它们都以“对象”开头,然后向下走,检查所有列表中的匹配.如果任何项目不匹配,那么前面的步骤是您最深的匹配基类型.

但是,由于“基地”是内部成员,我不确定如何建立链条.这是你可以使用Reflection确定的东西吗?

解决方法:

您可以使用反射来执行此操作.假设我们从Type实例而不是对象开始 – 这是更通用的,您可以简单地将对象列表转换为其运行时类型列表,以涵盖您提到的用例.

我们的想法是遍历每个输入类型的所有基类,并为每个输入类型增加一个“类型实例计数器”.执行此操作后,输入类型的所有公共基础必须使其计数器等于输入类型的数量.哪一个是派生最多的?轻松,选择任何输入类型并开始遍历其类型层次结构,直到找到一个共同的基础;该类型是派生最多的共同基础.

代码

我将使用此扩展方法:

public static IEnumerable<Type> TypeHierarchy(this Type type)
{
    do
    {
        yield return type;
        type = type.BaseType;
    } while (type != null);
}

然后允许这个实现 – 感谢LINQ,它读起来几乎像英语:

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

    var counts = new Dictionary<Type, int>();
    var total = types.Count();
    foreach(var type in types.SelectMany(t => t.TypeHierarchy()))
    {
        if (!counts.ContainsKey(type))
        {
            counts[type] = 1;
        }
        else
        {
            counts[type]++;
        }
    }

    return types.First().TypeHierarchy().First(t => counts[t] == total);
}

您可以使用例如

var types = new[] { typeof(MemoryStream), typeof(FileStream) };
Console.WriteLine(MostDerivedCommonBase(types)); // System.IO.Stream

更新

事后看来,很明显,构建类型字典也可以完全使用LINQ来完成.因此,如果紧凑是你的一杯茶,代码可以简化为:

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);
}

标签:c,reflection,inheritance,subclass
来源: https://codeday.me/bug/20190520/1141595.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有