Easiest way to get a common base class from a collection of types

后端 未结 6 1550
情书的邮戳
情书的邮戳 2020-12-17 05:07

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

6条回答
  •  天涯浪人
    2020-12-17 05:45

    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.

    I tested it with:

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

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

提交回复
热议问题