/// <summary> /// Copies fields from <paramref name="source"/> object to <paramref name="target"/> object. /// Types of both objects must be the same. /// </summary> /// <param name="tinfo">Type of both objects.</param> /// <param name="source">Source instance.</param> /// <param name="target">Target instance.</param> public static void MemberwiseClone(PhpTypeInfo tinfo, object source, object target) { Debug.Assert(tinfo != null); Debug.Assert(source != null); Debug.Assert(target != null); Debug.Assert(source.GetType() == target.GetType()); Debug.Assert(source.GetType() == tinfo.Type.AsType()); // copy CLR fields, skipping runtime fields foreach (var prop in TypeMembersUtils.EnumerateInstanceFields(source, Utilities.FuncExtensions.Identity <PhpPropertyInfo>(), null, null, ignoreRuntimeFields: true)) { var value = prop.Value.DeepCopy(); prop.Key.SetValue(null, target, value); } // fast copy of runtime fields var runtime_fields = tinfo.GetRuntimeFields(source); if (runtime_fields != null && runtime_fields.Count != 0) { tinfo.RuntimeFieldsHolder.SetValue(target, runtime_fields.Clone()); } // TODO: traits ? }
/// <summary> /// Returns names and properties of all instance properties or only PHP fields (including runtime fields). /// </summary> /// <param name="instance">The instance being serialized.</param> /// <param name="tinfo"><paramref name="instance"/> type info.</param> /// <returns>Name-value pairs. Names are properly formatted for serialization.</returns> public static IEnumerable <KeyValuePair <string, PhpValue> > EnumerateSerializableProperties(object /*!*/ instance, PhpTypeInfo tinfo) { return(TypeMembersUtils.EnumerateInstanceFields(instance, FormatSerializedPropertyName, TypeMembersUtils.s_keyToString, (m) => !m.IsReadOnly)); }
/// <summary> /// Returns names and properties of all instance properties or only PHP fields (including runtime fields). /// </summary> /// <param name="instance">The instance being serialized.</param> /// <param name="tinfo"><paramref name="instance"/> type info.</param> /// <returns>Name-value pairs. Names are properly formatted for serialization.</returns> public static IEnumerable <KeyValuePair <string, PhpValue> > EnumerateSerializableProperties(object /*!*/ instance, PhpTypeInfo tinfo) { return(TypeMembersUtils.EnumerateInstanceFields(instance, (f, d) => Serialization.FormatSerializedPropertyName(f, f.Name, d), (k) => k.ToString(), (f) => true)); }
/// <summary> /// Copies fields from <paramref name="source"/> object to <paramref name="target"/> object. /// Types of both objects must be the same. /// </summary> /// <param name="tinfo">Type of both objects.</param> /// <param name="source">Source instance.</param> /// <param name="target">Target instance.</param> public static void MemberwiseClone(PhpTypeInfo tinfo, object source, object target) { Debug.Assert(tinfo != null); Debug.Assert(source != null); Debug.Assert(target != null); Debug.Assert(source.GetType() == target.GetType()); Debug.Assert(source.GetType() == tinfo.Type.AsType()); // copy CLR fields, skipping runtime fields foreach (var prop in TypeMembersUtils.EnumerateInstanceFields(source, (m, d) => m, null, null, true)) { var value = prop.Value.DeepCopy(); if (prop.Key is FieldInfo f) { f.SetValue(target, value.ToClr(f.FieldType)); } else if (prop.Key is PropertyInfo p) { p.SetValue(target, value.ToClr(p.PropertyType)); } } // fast copy of runtime fields var runtime_fields = tinfo.GetRuntimeFields(source); if (runtime_fields != null && runtime_fields.Count != 0) { tinfo.RuntimeFieldsHolder.SetValue(target, runtime_fields.DeepCopy()); } }
/// <summary> /// Returns names and properties of all instance properties or only PHP fields (including runtime fields). /// </summary> /// <param name="instance">The instance being serialized.</param> /// <param name="tinfo"><paramref name="instance"/> type info.</param> /// <returns>Name-value pairs. Names are properly formatted for serialization.</returns> public static IEnumerable <KeyValuePair <string, PhpValue> > EnumerateSerializableProperties(object /*!*/ instance, PhpTypeInfo tinfo) { return(TypeMembersUtils.EnumerateInstanceFields(instance, (m, d) => FormatSerializedPropertyName(m is FieldInfo f ? (PhpPropertyInfo) new PhpPropertyInfo.ClrFieldProperty(tinfo, f) : new PhpPropertyInfo.ClrProperty(tinfo, (PropertyInfo)m), d), (k) => k.ToString(), (m) => (m is PropertyInfo p ? p.SetMethod != null : true) && TypeMembersUtils.s_notClrInternalFieldsPredicate(m))); }
/// <summary> /// Returns names and properties of all instance properties or only PHP fields (including runtime fields). /// </summary> /// <param name="instance">The instance being serialized.</param> /// <param name="tinfo"><paramref name="instance"/> type info.</param> /// <returns>Name-value pairs. Names are properly formatted for serialization.</returns> public static IEnumerable <KeyValuePair <string, PhpValue> > EnumerateSerializableProperties(object /*!*/ instance, PhpTypeInfo tinfo) { return(TypeMembersUtils.EnumerateInstanceFields(instance, (m, d) => FormatSerializedPropertyName(m is FieldInfo f ? (PhpPropertyInfo) new PhpPropertyInfo.ClrFieldProperty(tinfo, f) : new PhpPropertyInfo.ClrProperty(tinfo, (PropertyInfo)m), d), (k) => k.ToString(), (m) => true)); }
/// <summary> /// Copies fields from <paramref name="source"/> object to <paramref name="target"/> object. /// Types of both objects must be the same. /// </summary> /// <param name="tinfo">Type of both objects.</param> /// <param name="source">Source instance.</param> /// <param name="target">Target instance.</param> public static void MemberwiseClone(PhpTypeInfo tinfo, object source, object target) { Debug.Assert(tinfo != null); Debug.Assert(source != null); Debug.Assert(target != null); Debug.Assert(source.GetType() == target.GetType()); Debug.Assert(source.GetType() == tinfo.Type.AsType()); // copy CLR fields, skipping runtime fields foreach (var fldvalue in TypeMembersUtils.EnumerateInstanceFields(source, (f, d) => f, null, null, true)) { fldvalue.Key.SetValue(target, fldvalue.Value.DeepCopy()); } // fast copy of runtime fields var runtime_fields = tinfo.GetRuntimeFields(source); if (runtime_fields != null && runtime_fields.Count != 0) { tinfo.RuntimeFieldsHolder.SetValue(target, runtime_fields.DeepCopy()); } }