27 using System.Collections.Generic;
28 using System.ComponentModel;
30 using System.Reflection;
31 using System.Runtime.CompilerServices;
33 namespace SiliconStudio.Core.Reflection
40 private static readonly List<IMemberDescriptor> EmptyMembers =
new List<IMemberDescriptor>();
41 protected static readonly
string SystemCollectionsNamespace = typeof(
int).Namespace;
43 private static readonly
object[] EmptyObjectArray =
new object[0];
45 private readonly Type type;
47 private Dictionary<string, IMemberDescriptor> mapMembers;
59 if (factory == null)
throw new ArgumentNullException(
"factory");
60 if (type == null)
throw new ArgumentNullException(
"type");
62 this.factory = factory;
63 Category = DescriptorCategory.Object;
67 this.style = styleAttribute != null ? styleAttribute.Style : DataStyle.Any;
68 this.IsCompilerGenerated = AttributeRegistry.GetAttribute<CompilerGeneratedAttribute>(type) != null;
76 var memberList = PrepareMembers();
81 memberList.Sort(SortMembers);
84 this.members = memberList.ToArray();
87 if (members.Length <= 0)
return;
89 mapMembers =
new Dictionary<string, IMemberDescriptor>(members.Length);
91 foreach (var member
in members)
94 if (mapMembers.TryGetValue(member.Name, out existingMember))
96 throw new InvalidOperationException(
"Failed to get ObjectDescriptor for type [{0}]. The member [{1}] cannot be registered as a member with the same name is already registered [{2}]".ToFormat(type.FullName, member, existingMember));
99 mapMembers.Add(member.Name, member);
106 if (left.
Order.HasValue || right.
Order.HasValue)
108 var leftOrder = left.Order.HasValue ? left.Order.Value : int.MaxValue;
109 var rightOrder = right.Order.HasValue ? right.Order.Value : int.MaxValue;
110 return leftOrder.CompareTo(rightOrder);
114 return string.CompareOrdinal(left.Name, right.Name);
147 return members.Length;
151 public bool HasMembers
155 return members.Length > 0;
178 if (mapMembers != null)
180 mapMembers.TryGetValue(name, out member);
186 public bool IsCompilerGenerated {
get;
private set; }
190 return mapMembers != null && mapMembers.ContainsKey(memberName);
195 if (type == typeof(Type))
201 var memberList = (from propertyInfo in type.GetProperties(BindingFlags.Instance | BindingFlags.Public)
203 propertyInfo.CanRead && propertyInfo.GetGetMethod(
false) != null &&
204 propertyInfo.GetIndexParameters().Length == 0 &&
205 IsMemberToVisit(propertyInfo)
208 where PrepareMember(member)
209 select member).Cast<IMemberDescriptor>().ToList();
212 memberList.AddRange((from fieldInfo in type.GetFields(BindingFlags.Instance | BindingFlags.Public)
213 where fieldInfo.IsPublic &&
214 IsMemberToVisit(fieldInfo)
217 where PrepareMember(member)
226 if (memberInfo is PropertyInfo && memberInfo.Name ==
"SyncRoot" && memberInfo.DeclaringType != null && (memberInfo.DeclaringType.Namespace ??
string.Empty).StartsWith(SystemCollectionsNamespace))
231 Type memberType = null;
232 var fieldInfo = memberInfo as FieldInfo;
233 if (fieldInfo != null)
235 memberType = fieldInfo.FieldType;
239 var propertyInfo = memberInfo as PropertyInfo;
240 if (propertyInfo != null)
242 memberType = propertyInfo.PropertyType;
246 if (memberType != null)
248 if (typeof(Delegate).IsAssignableFrom(memberType))
264 var memberType = member.Type;
269 member.Mode = DataMemberMode.Assign;
274 member.Mode = (memberType != typeof(
string) && memberType.IsClass) || memberType.IsInterface || type.IsAnonymous() ? DataMemberMode.Content : DataMemberMode.Never;
278 var styleAttribute = AttributeRegistry.GetAttribute<
DataStyleAttribute>(member.MemberInfo);
279 member.Style = styleAttribute != null ? styleAttribute.Style : DataStyle.Any;
282 var memberAttribute = AttributeRegistry.GetAttribute<
DataMemberAttribute>(member.MemberInfo,
false);
283 if (memberAttribute != null)
289 throw new ArgumentException(
"{0} {1} is not writeable by {2}.".ToFormat(memberType.FullName, member.
Name, memberAttribute.Mode.ToString()));
294 member.Mode = memberAttribute.Mode;
296 member.Order = memberAttribute.Order;
301 if (!memberType.IsArray)
302 throw new InvalidOperationException(
"{0} {1} of {2} is not an array. Can not be serialized as binary."
303 .ToFormat(memberType.FullName, member.
Name, type.FullName));
304 if (!memberType.GetElementType().IsPureValueType())
305 throw new InvalidOperationException(
"{0} is not a pure ValueType. {1} {2} of {3} can not serialize as binary.".ToFormat(memberType.GetElementType(), memberType.FullName, member.Name, type.FullName));
314 if (memberAttribute != null && !
string.IsNullOrEmpty(memberAttribute.Name))
316 member.Name = memberAttribute.Name;
A IMemberDescriptor for a PropertyInfo
SharpDX.DirectWrite.Factory Factory
When specified on a property or field, it will not be used when serializing/deserializing.
Default implementation of a ITypeDescriptor.
Describe a member of an object.
A IMemberDescriptor for a FieldInfo
A registry for all attributes.
DescriptorCategory
A category used by ITypeDescriptor.
Specify the way to store a property or field of some class or structure.
int Order
Gets the order of this member. Default is -1, meaning that it is using the alphabetical order based o...
virtual void Initialize()
An attribute to modify the output style of a sequence or mapping. This attribute can be apply directl...
virtual bool PrepareMember(MemberDescriptorBase member)
bool Contains(string memberName)
Determines whether this instance contains a member with the specified member name.
Provides access members of a type.
SiliconStudio.Core.Reflection.AttributeRegistry AttributeRegistry
virtual List< IMemberDescriptor > PrepareMembers()
bool IsMemberToVisit(MemberInfo memberInfo)
Base class for IMemberDescriptor for a MemberInfo
ObjectDescriptor(ITypeDescriptorFactory factory, Type type)
Initializes a new instance of the ObjectDescriptor class.
A factory to create an instance of a ITypeDescriptor
A default implementation for IAttributeRegistry. This implementation allows to retrieve default attri...
DataStyle
Specifies the style used for textual serialization when an array/list or a dictionary/map must be ser...