从类型集合中获取公共基类的最简单方法

Mic*_*cah 5 .net c# linq reflection

我正在构建一个自定义属性网格,用于显示集合中项目的属性。我想要做的是仅显示网格中每个项目共有的属性。我假设最好的方法是找到集合中每种类型的公共基类并显示其属性。有没有更简单的方法?您能给我一个执行此操作的最佳方法的代码示例吗?

Ton*_*son 4

您可以使用持续检查公共基类的方法来完成此操作。我使用 Type 类的 BaseClass 功能很快地写了这个。您不必使用数组、列表或其他 IEnumerable 可以对此进行小的修改。

我用以下方法测试了它:

static void Main(string[] args)
{
    Console.WriteLine("Common Types: " + GetCommonBaseClass(new Type[] {typeof(OleDbCommand), typeof(OdbcCommand), typeof(SqlCommand)}).ToString());   
}
Run Code Online (Sandbox Code Playgroud)

并得到了DbCommand的正确答案。这是我的代码。

    static Type GetCommonBaseClass(Type[] types)
    {
        if (types.Length == 0)
            return (typeof(object));
        else if (types.Length == 1)
            return (types[0]);

        // Copy the parameter so we can substitute base class types in the array without messing up the caller
        Type[] temp = new Type[types.Length];

        for (int i = 0; i < types.Length; i++)
        {
            temp[i] = types[i];
        }

        bool checkPass = false;

        Type tested = null;

        while (!checkPass)
        {
            tested = temp[0];

            checkPass = true;

            for (int i = 1; i < temp.Length; i++)
            {
                if (tested.Equals(temp[i]))
                    continue;
                else
                {
                    // If the tested common basetype (current) is the indexed type's base type
                    // then we can continue with the test by making the indexed type to be its base type
                    if (tested.Equals(temp[i].BaseType))
                    {
                        temp[i] = temp[i].BaseType;
                        continue;
                    }
                    // If the tested type is the indexed type's base type, then we need to change all indexed types
                    // before the current type (which are all identical) to be that base type and restart this loop
                    else if (tested.BaseType.Equals(temp[i]))
                    {
                        for (int j = 0; j <= i - 1; j++)
                        {
                            temp[j] = temp[j].BaseType;
                        }

                        checkPass = false;
                        break;
                    }
                    // The indexed type and the tested type are not related
                    // So make everything from index 0 up to and including the current indexed type to be their base type
                    // because the common base type must be further back
                    else
                    {
                        for (int j = 0; j <= i; j++)
                        {
                            temp[j] = temp[j].BaseType;
                        }

                        checkPass = false;
                        break;
                    }
                }
            }

            // If execution has reached here and checkPass is true, we have found our common base type, 
            // if checkPass is false, the process starts over with the modified types
        }

        // There's always at least object
        return tested;
    }
Run Code Online (Sandbox Code Playgroud)