最简单的方法从类型的集合得到一个共同的基类最简单、类型、方法

2023-09-03 01:12:50 作者:沦落

我建立一个自定义属性网格,集合中显示项目的属性。我想要做的是只显示在那些共同之间的每一项电网的特性。我假设要做到这一点是找到集合中的每个类型的公共基类,并显示其属性的最佳方法。有没有更简单的方法?你能给我的最好的办法一个code的例子来做到这一点?

I'm building a custom property grid that displays the properties of items in a collection. What I want to do is show only the properties in the grid that are common amongst each item. I am assuming the best way to do this would be to find the the common base class of each type in the collection and display it's properties. Is there any easier way? Can you give me a code example of the best approach to do this?

推荐答案

您可以与不断检查公共基类的方法做到这一点。我写了这个,快,使用Type类的BaseClass的功能。你不必使用数组,列表或其它的IEnumerable可以与小的修改这个工作。

You can do this with a method that keeps checking for common base classes. I wrote up this, quickly, using the BaseClass feature of the Type class. You don't have to use an array, a list or other IEnumerable can work with small modifications to this.

我和测试它:

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

和得到的DbCommand的正确答案。这是我的code。

And got the right answer of DbCommand. Here is my code.

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