Exemplo n.º 1
0
        // Gets the class definition for an object `obj`, applying transformations like type name mappings
        public virtual ClassDescription GetClassDescription(object obj)
        {
            if (obj == null)
            {
                throw new ArgumentNullException("obj");
            }
            var type = obj.GetType();

            ClassDescription cachedDescription;

            if (cache.TryGetValue(type, out cachedDescription))
            {
                return(cachedDescription);
            }

            var serializable = Helper.GetSerializableFields(type);
            var classMembers = new List <BasicMemberWrapper>();

            // add fields and properties
            classMembers.AddRange(serializable.Fields.Select(fieldInfo => new BasicMemberWrapper(fieldInfo.Name, fieldInfo)));
            foreach (var propertyInfo in serializable.Properties)
            {
                var name = propertyInfo.Name;

                // There is no reflection API that allows us to check whether a variable hides
                // another variable (for example, with the `new` keyword). We need to access the
                // property by name and catch an ambiguous match.
                //
                // Currently, the logic following that which only allows variables from the
                // declaring type forward doesn't work in all cases work in all cases. Assume we
                // have an inheritence hierarchy of `operating-system -> linux -> arch-linux`. In
                // this case, if both `operating-system` and `linux` declare a `Name` field that is
                // not inherited but `arch-linux` does not then we expect the `Name` field from
                // `linux` to be serialized, but as it is both `Name` fields from `operating-system`
                // and `linux` are ignored.
                //
                //
                // In practice it does not matter for my current use cases, but this may trip up
                // some people if I ever open source this
                try
                {
                    type.GetProperty(name);
                }
                catch (AmbiguousMatchException)
                {
                    if (type.DeclaringType != type)
                    {
                        continue;
                    }
                }

                var classMember = new BasicMemberWrapper(name, propertyInfo);
                classMembers.Add(classMember);
            }

            var typeName = serializationContext.GetAlias(type.FullName);

            return(new BasicObjectClassDescription(typeName, classMembers.Cast <IMemberWrapper>().ToArray(), GetIsExternalizable(obj), GetIsDynamic(obj)));
        }
Exemplo n.º 2
0
        // Gets the class definition for an object `obj`, applying transformations like type name mappings
        public virtual ClassDescription GetClassDescription(object obj)
        {
            if (obj == null)
                throw new ArgumentNullException("obj");
            var type = obj.GetType();

            ClassDescription cachedDescription;
            if (cache.TryGetValue(type, out cachedDescription))
                return cachedDescription;

            var serializable = Helper.GetSerializableFields(type);
            var classMembers = new List<BasicMemberWrapper>();

            // add fields and properties
            classMembers.AddRange(serializable.Fields.Select(fieldInfo => new BasicMemberWrapper(fieldInfo.Name, fieldInfo)));
            foreach (var propertyInfo in serializable.Properties)
            {
                var name = propertyInfo.Name;

                // There is no reflection API that allows us to check whether a variable hides
                // another variable (for example, with the `new` keyword). We need to access the
                // property by name and catch an ambiguous match.
                //
                // Currently, the logic following that which only allows variables from the
                // declaring type forward doesn't work in all cases work in all cases. Assume we
                // have an inheritence hierarchy of `operating-system -> linux -> arch-linux`. In
                // this case, if both `operating-system` and `linux` declare a `Name` field that is
                // not inherited but `arch-linux` does not then we expect the `Name` field from
                // `linux` to be serialized, but as it is both `Name` fields from `operating-system`
                // and `linux` are ignored.
                //
                //
                // In practice it does not matter for my current use cases, but this may trip up
                // some people if I ever open source this
                try
                {
                    type.GetProperty(name);
                }
                catch (AmbiguousMatchException)
                {
                    if (type.DeclaringType != type)
                        continue;
                }

                var classMember = new BasicMemberWrapper(name, propertyInfo);
                classMembers.Add(classMember);
            }

            var typeName = serializationContext.GetAlias(type.FullName);
            return new BasicObjectClassDescription(typeName, classMembers.Cast<IMemberWrapper>().ToArray(), GetIsExternalizable(obj), GetIsDynamic(obj));
        }