How could Reflection not lead to code smells?

后端 未结 18 2127
失恋的感觉
失恋的感觉 2020-12-12 15:02

I come from low level languages - C++ is the highest level I program in.

Recently I came across Reflection, and I just cannot fathom how it could be used without cod

18条回答
  •  甜味超标
    2020-12-12 15:18

    With reflection, you can write a small amount of domain independent code that doesn't need to change often versus writing a lot more domain dependent code that needs to change more frequently (such as when properties are added/removed). With established conventions in your project, you can perform common functions based on the presence of certain properties, attributes, etc. Data transformation of objects between different domains is one example where reflection really comes in handy.

    Or a more simple example within a domain, where you want to transform data from the database to data objects without needing to modify the transformation code when properties change, so long as conventions are maintained (in this case matching property names and a specific attribute):

        ///--------------------------------------------------------------------------------
        /// Transform data from the input data reader into the output object.  Each
        /// element to be transformed must have the DataElement attribute associated with
        /// it.
        ///
        /// The database reader with the input data.
        /// The output object to be populated with the input data.
        /// Data elements to filter out of the transformation.
        ///--------------------------------------------------------------------------------
        public static void TransformDataFromDbReader(DbDataReader inputReader, IDataObject outputObject, NameObjectCollection filterElements)
        {
            try
            {
                // add all public properties with the DataElement attribute to the output object
                foreach (PropertyInfo loopInfo in outputObject.GetType().GetProperties())
                {
                    foreach (object loopAttribute in loopInfo.GetCustomAttributes(true))
                    {
                        if (loopAttribute is DataElementAttribute)
                        {
                            // get name of property to transform
                            string transformName = DataHelper.GetString(((DataElementAttribute)loopAttribute).ElementName).Trim().ToLower();
                            if (transformName == String.Empty)
                            {
                                transformName = loopInfo.Name.Trim().ToLower();
                            }
    
                            // do transform if not in filter field list
                            if (filterElements == null || DataHelper.GetString(filterElements[transformName]) == String.Empty)
                            {
                                for (int i = 0; i < inputReader.FieldCount; i++)
                                {
                                    if (inputReader.GetName(i).Trim().ToLower() == transformName)
                                    {
                                        // set value, based on system type
                                        loopInfo.SetValue(outputObject, DataHelper.GetValueFromSystemType(inputReader[i], loopInfo.PropertyType.UnderlyingSystemType.FullName, false), null);
                                    }
                                }
                            }
                        }
                    }
                }
    
                // add all fields with the DataElement attribute to the output object
                foreach (FieldInfo loopInfo in outputObject.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance))
                {
                    foreach (object loopAttribute in loopInfo.GetCustomAttributes(true))
                    {
                        if (loopAttribute is DataElementAttribute)
                        {
                            // get name of field to transform
                            string transformName = DataHelper.GetString(((DataElementAttribute)loopAttribute).ElementName).Trim().ToLower();
                            if (transformName == String.Empty)
                            {
                                transformName = loopInfo.Name.Trim().ToLower();
                            }
    
                            // do transform if not in filter field list
                            if (filterElements == null || DataHelper.GetString(filterElements[transformName]) == String.Empty)
                            {
                                for (int i = 0; i < inputReader.FieldCount; i++)
                                {
                                    if (inputReader.GetName(i).Trim().ToLower() == transformName)
                                    {
                                        // set value, based on system type
                                        loopInfo.SetValue(outputObject, DataHelper.GetValueFromSystemType(inputReader[i], loopInfo.FieldType.UnderlyingSystemType.FullName, false));
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                bool reThrow = ExceptionHandler.HandleException(ex);
                if (reThrow) throw;
            }
        }
    

提交回复
热议问题