예제 #1
0
        public static PropertyAccessor Create(PropertyInfo propertyInfo)
        {
            PropertyAccessor accessor;

            lock (accessorCache)
            {
                if (!accessorCache.TryGetValue(propertyInfo, out accessor))
                {
                    accessorCache.Add(propertyInfo, accessor = new PropertyAccessor(propertyInfo));
                }
            }

            return(accessor);
        }
        public static TOut TransposeExact <TIn, TOut>(this TIn input)
        {
            Type inType      = typeof(TIn);
            Type outType     = typeof(TOut);
            TOut returnValue = Activator.CreateInstance <TOut>();

            foreach (var property in inType.GetProperties())
            {
                var outProperty = outType.GetProperty(property.Name);
                var value       = property.GetValue(input, null);

                if (property.PropertyType.Name.Contains("Collection") || property.PropertyType.Name.Contains("List"))
                {
                    var collectionEntryType = property.PropertyType.GetGenericArguments().Single();

                    if (!collectionEntryType.IsValueType && collectionEntryType != typeof(string))
                    {
                        object collection     = PropertyAccessor.Create(property).Get(input);
                        object instance       = Activator.CreateInstance(outProperty.PropertyType);
                        IList  instanceAsList = (IList)instance;

                        foreach (object c in ((IList)collection))
                        {
                            object outc = InvokeTransposeExact(c, c.GetType(), outProperty.PropertyType.GetGenericArguments().Single());
                            instanceAsList.Add(outc);
                        }

                        PropertyAccessor.Create(outProperty).Set(returnValue, instance);
                        continue;
                    }

                    PropertyAccessor.Create(outProperty).Set(returnValue, value);
                    continue;
                }
                if (!property.PropertyType.IsValueType && property.PropertyType != typeof(string))
                {
                    value = InvokeTransposeExact(PropertyAccessor.Create(property).Get(input), property.PropertyType,
                                                 outProperty.PropertyType);
                }

                PropertyAccessor.Create(outProperty).Set(returnValue, value);
            }

            return(returnValue);
        }
 public static PropertyAccessor GetAccessor(this PropertyInfo propertyInfo)
 {
     return(PropertyAccessor.Create(propertyInfo));
 }
 public static PropertyAccessor GetPropertyAccessor(this Type candidate, string propertyName)
 {
     return(PropertyAccessor.Create(candidate.GetProperty(propertyName)));
 }
        public static TOut Transpose <TIn, TOut>(this TIn input)
        {
            Type outType = typeof(TOut);
            Type inType  = typeof(TIn);

            TOut result;

            if (!outType.IsValueType && outType.HasParameterlessConstructor())
            {
                result = Activator.CreateInstance <TOut>();
            }
            else
            {
                result = default(TOut);
            }

            FieldInfo[] fields = inType.GetFields();
            IEnumerable <Tuple <FieldInfo, FieldInfo> > fieldInfos = fields.Select(f => new Tuple <FieldInfo, FieldInfo>(f, outType.GetField(f.Name)));

            foreach (Tuple <FieldInfo, FieldInfo> tuple in fieldInfos.Where(t => t.Item2 != null))
            {
                FieldInfo sourceField = tuple.Item1;
                FieldInfo targetField = tuple.Item2;

                if (!sourceField.FieldType.IsValueType && sourceField.FieldType != typeof(string) &&
                    !sourceField.FieldType.GetInterfaces().Contains(typeof(ICloneable)))
                {
                    throw new InvalidOperationException(
                              string.Format(
                                  "Cannot transpose from field {0} of type {2} because it is of type {1} which is not a value type or ICloneable",
                                  sourceField.Name, sourceField.FieldType.Name, inType.Name));
                }

                if (!targetField.FieldType.IsValueType && targetField.FieldType != typeof(string) &&
                    !targetField.FieldType.GetInterfaces().Contains(typeof(ICloneable)))
                {
                    throw new InvalidOperationException(
                              string.Format(
                                  "Cannot transpose to field {0} of type {2} because it is of type {1} which is not a value type or ICloneable",
                                  targetField.Name, targetField.FieldType.Name, outType.Name));
                }

                if (sourceField.FieldType != targetField.FieldType)
                {
                    throw new InvalidOperationException(
                              string.Format(
                                  "Cannot transpose field {0} because in type {1} it is of type {2} and in type {3} it is of type {4}",
                                  sourceField.Name, inType.Name, sourceField.FieldType.Name, outType.Name,
                                  targetField.FieldType.Name));
                }

                object value = sourceField.GetValue(input);

                if (value is ICloneable)
                {
                    value = ((ICloneable)value).Clone();
                }

                targetField.SetValue(result, value);
            }

            PropertyInfo[] properties = inType.GetProperties();
            IEnumerable <Tuple <PropertyInfo, PropertyInfo> > propertyInfos =
                properties.Select(p => new Tuple <PropertyInfo, PropertyInfo>(p, outType.GetProperty(p.Name)));

            foreach (Tuple <PropertyInfo, PropertyInfo> tuple in propertyInfos.Where(t => t.Item2 != null && t.Item2.GetSetMethod() != null))
            {
                PropertyInfo sourceProperty = tuple.Item1;
                PropertyInfo targetProperty = tuple.Item2;

                if (!sourceProperty.PropertyType.IsValueType && sourceProperty.PropertyType != typeof(string) && !sourceProperty.PropertyType.GetInterfaces().Contains(typeof(ICloneable)))
                {
                    throw new InvalidOperationException(string.Format("Cannot transpose from property {0} of type {2} because it is of type {1} which is not a value type or ICloneable", sourceProperty.Name, sourceProperty.PropertyType.Name, inType.Name));
                }

                if (!targetProperty.PropertyType.IsValueType && targetProperty.PropertyType != typeof(string) && !targetProperty.PropertyType.GetInterfaces().Contains(typeof(ICloneable)))
                {
                    throw new InvalidOperationException(string.Format("Cannot transpose to property {0} of type {2} because it is of type {1} which is not a value type or ICloneable", targetProperty.Name, targetProperty.PropertyType.Name, outType.Name));
                }

                if (sourceProperty.PropertyType != targetProperty.PropertyType)
                {
                    throw new InvalidOperationException(
                              string.Format(
                                  "Cannot transpose property {0} because in type {1} it is of type {2} and in type {3} it is of type {4}",
                                  sourceProperty.Name, inType.Name, sourceProperty.PropertyType.Name, outType.Name,
                                  targetProperty.PropertyType.Name));
                }

                object value = sourceProperty.GetValue(input);

                if (value is ICloneable)
                {
                    value = ((ICloneable)value).Clone();
                }

                PropertyAccessor.Create(targetProperty).Set(result, value);
            }

            return(result);
        }
 public static object GetValue(this PropertyInfo propertyInfo, object obj)
 {
     return(PropertyAccessor.Create(propertyInfo).Get(obj));
 }
 public static void SetValue(this PropertyInfo propertyInfo, object obj, object value)
 {
     PropertyAccessor.Create(propertyInfo).Set(obj, value);
 }