// 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))); }
// 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)); }