public void CanConvertFrom()
        {
            NullableConverter converter = new NullableConverter(typeof(MyType?));

            Assert.IsTrue(converter.CanConvertFrom(null, typeof(MyType)), "#1");
            Assert.IsFalse(converter.CanConvertFrom(null, typeof(object)), "#2");
        }
        internal virtual T GetValue <T> (object target)
        {
            var    converted  = default(T);
            object value      = null;
            bool   canConvert = false;

            try {
                value = PropertyDescriptor.GetValue(PropertyProvider);
                var currentType    = typeof(T);
                var underlyingType = Nullable.GetUnderlyingType(currentType);

                //proppy has some editors based in nullable types
                if (underlyingType != null)
                {
                    var converterNullable = new NullableConverter(currentType);
                    if (converterNullable.CanConvertFrom(underlyingType))
                    {
                        object notNullableValue = Convert.ChangeType(value, underlyingType);
                        return((T)converterNullable.ConvertFrom(notNullableValue));
                    }
                }

                var tc = PropertyDescriptor.Converter;
                canConvert = tc.CanConvertTo(currentType);
                if (canConvert)
                {
                    converted = (T)tc.ConvertTo(value, currentType);
                }
                else
                {
                    converted = (T)Convert.ChangeType(value, currentType);
                }
            } catch (Exception ex) {
                LogInternalError($"Error trying to get and convert value:'{value}' canconvert: {canConvert} T:{typeof (T).FullName} ", ex);
            }
            return(converted);
        }
        /// <summary>
        /// Tries to read a column value from a data reader and return the typed value.
        /// </summary>
        /// <remarks>If the specified column is not found or the types do not match, returns default value.</remarks>
        /// <typeparam name="TField">The type of the field that we are reading.</typeparam>
        /// <param name="reader">The data reader that should contain the column value.</param>
        /// <param name="name">The name of the column to read.</param>
        /// <returns>A value of type TField.</returns>
        public static TField Get <TField>(this DbDataReader reader, string name)
        {
            var value = reader[name];

            // check for null and return default
            if (value == null || value == DBNull.Value)
            {
                return(default(TField));
            }

            // direct cast if we can...
            var returnType = typeof(TField);

            if (value.GetType() == returnType)
            {
                return((TField)value);
            }

            // nullable types require different container
            if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                var converter = new NullableConverter(returnType);
                if (converter.CanConvertFrom(value.GetType()))
                {
                    return((TField)converter.ConvertFrom(value));
                }
            }
            else
            {
                return((TField)Convert.ChangeType(value, typeof(TField)));
            }

            // We tried...we failed...
            throw new InvalidOperationException(
                      $"Unable to convert from database field ({value.GetType().FullName}) to object ({returnType.FullName})");
        }
예제 #4
0
        /// <summary>
        /// 将动态类型转为指定类型实体
        /// </summary>
        /// <param name="data"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        private static object DynamicToEntity(ExpandoObject data, Type type)
        {
            var entity = Activator.CreateInstance(type);

            var dic = data as IDictionary <string, object>;

            foreach (var item in dic)
            {
                if (item.Value == null)
                {
                    continue;
                }

                var type_value = item.Value.GetType();

                if (type_value == typeof(DBNull))
                {
                    continue;
                }

                var prop = type.GetProperty(item.Key, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static);

                if (prop == null)
                {
                    continue;
                }

                object value = item.Value;

                if (type_value != prop.PropertyType)
                {
                    if (type_value == typeof(List <object>))
                    {
                        var valueList    = Activator.CreateInstance(prop.PropertyType);
                        var dicValueList = value as List <object>;

                        foreach (var valueItem in dicValueList)
                        {
                            prop.PropertyType.GetMethod("Add")
                            .Invoke(valueList, new object[] {
                                DynamicToEntity(valueItem as ExpandoObject, prop.PropertyType.GenericTypeArguments[0])
                            });
                        }

                        value = valueList;
                    }
                    else if (type_value == typeof(ExpandoObject))
                    {
                        value = DynamicToEntity(item.Value as ExpandoObject, prop.PropertyType);
                    }
                    else if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable <>)))
                    {
                        NullableConverter newNullableConverter = new NullableConverter(prop.PropertyType);
                        try
                        {
                            if (!newNullableConverter.CanConvertFrom(item.Value.GetType()))
                            {
                                value = Convert.ChangeType(item.Value, newNullableConverter.UnderlyingType);
                            }
                            else
                            {
                                value = newNullableConverter.ConvertFrom(item.Value);
                            }
                        }
#pragma warning disable CA1031 // Do not catch general exception types
                        catch
                        {
                            value = newNullableConverter.ConvertFromString(item.Value?.ToString());
                        }
#pragma warning restore CA1031 // Do not catch general exception types
                    }
                    else
                    {
                        value = Convert.ChangeType(item.Value, prop.PropertyType);
                    }
                }
                prop.SetValue(entity, value);
            }
            return(entity);
        }