コード例 #1
0
ファイル: XamlNode.cs プロジェクト: pmq20/mono_forked
        // Note that this returns XamlMember which might not actually appear in XamlObjectReader. For example, XamlLanguage.Items won't be returned when there is no item in the collection.
        public static IEnumerable <XamlMember> GetAllObjectReaderMembersByType(this XamlType type, IValueSerializerContext vsctx)
        {
            if (type.HasPositionalParameters(vsctx))
            {
                yield return(XamlLanguage.PositionalParameters);

                yield break;
            }

            // Note that if the XamlType has the default constructor, we don't need "Arguments".
            IEnumerable <XamlMember> args = type.ConstructionRequiresArguments ? type.GetSortedConstructorArguments() : null;

            if (args != null && args.Any())
            {
                yield return(XamlLanguage.Arguments);
            }

            if (type.IsContentValue(vsctx))
            {
                yield return(XamlLanguage.Initialization);

                yield break;
            }

            if (type.IsDictionary)
            {
                yield return(XamlLanguage.Items);

                yield break;
            }

            foreach (var m in type.GetAllMembers())
            {
                // do not read constructor arguments twice (they are written inside Arguments).
                if (args != null && args.Contains(m))
                {
                    continue;
                }
                // do not return non-public members (of non-collection/xdata). Not sure why .NET filters out them though.
                if (!m.IsReadPublic)
                {
                    continue;
                }
                if (!m.IsWritePublic &&
                    !m.Type.IsXData &&
                    !m.Type.IsArray &&
                    !m.Type.IsCollection &&
                    !m.Type.IsDictionary)
                {
                    continue;
                }

                yield return(m);
            }

            if (type.IsCollection)
            {
                yield return(XamlLanguage.Items);
            }
        }
コード例 #2
0
        // It expects that it is not invoked when there is no value to
        // assign.
        // When it is passed null, then it returns a default instance.
        // For example, passing null as Int32 results in 0.
        // But do not immediately try to instantiate with the type, since the type might be abstract.
        object GetCorrectlyTypedValue(XamlMember xm, XamlType xt, object value, bool fallbackToString = false)
        {
            try
            {
                if (value == null)
                {
                    if (xt.IsContentValue(service_provider)) // it is for collection/dictionary key and item
                    {
                        return(null);
                    }
                    else
                    {
                        return(xt.IsNullable ? null : xt.Invoker.CreateInstance(new object[0]));
                    }
                }
                if (ReferenceEquals(xt, null))
                {
                    return(value);
                }

                // Not sure if this is really required though...
                var vt = sctx.GetXamlType(value.GetType());
                if (vt.CanAssignTo(xt))
                {
                    return(value);
                }

                // FIXME: this could be generalized by some means, but I cannot find any.
                if (xt.UnderlyingType == typeof(XamlType) && value is string)
                {
                    value = ResolveTypeFromName((string)value);
                }

                // FIXME: this could be generalized by some means, but I cannot find any.
                if (xt.UnderlyingType == typeof(Type))
                {
                    value = new TypeExtension((string)value).ProvideValue(service_provider);
                }
                if (ReferenceEquals(xt, XamlLanguage.Type) && value is string)
                {
                    value = new TypeExtension((string)value);
                }

                if (IsAllowedType(xt, value))
                {
                    return(value);
                }

                var xtc = xm?.TypeConverter ?? xt.TypeConverter;
                if (xtc != null && value != null)
                {
                    var tc = xtc.ConverterInstance;
                    if (tc != null && tc.CanConvertFrom(service_provider, value.GetType()))
                    {
                        value = tc.ConvertFrom(service_provider, CultureInfo.InvariantCulture, value);
                    }
                    return(value);
                }
            }
            catch (Exception ex)
            {
                // For + ex.Message, the runtime should print InnerException message like .NET does.
                throw WithLineInfo(new XamlObjectWriterException(
                                       String.Format("Could not convert object \'{0}' (of type {1}) to {2}: ", value, value != null ? (object)value.GetType() : "(null)", xt) + ex.Message,
                                       ex));
            }

            return(fallbackToString ?
                   value :
                   throw WithLineInfo(new XamlObjectWriterException(
                                          String.Format("Value '{0}' (of type {1}) is not of or convertible to type {2} (member {3})", value, value != null ? (object)value.GetType() : "(null)", xt, xm),
                                          null)));
        }