/// <summary> /// Creates a new ObjectReader instance for reading the supplied data /// </summary> /// <param name="type">The expected Type of the information to be read</param> /// <param name="source">The sequence of objects to represent</param> /// <param name="members">The members that should be exposed to the reader</param> public ObjectReader(Type type, IEnumerable source, params string[] members) { if (source == null) { throw new ArgumentOutOfRangeException("source"); } bool allMembers = members == null || members.Length == 0; this.accessor = TypeAccessor.Create(type); if (accessor.GetMembersSupported) { var typeMembers = this.accessor.GetMembers(); if (allMembers) { members = new string[typeMembers.Count]; for (int i = 0; i < members.Length; i++) { members[i] = typeMembers[i].Name; } } this.allowNull = new BitArray(members.Length); this.effectiveTypes = new Type[members.Length]; for (int i = 0; i < members.Length; i++) { Type memberType = null; bool allowNull = true; string hunt = members[i]; foreach (var member in typeMembers) { if (member.Name == hunt) { if (memberType == null) { var tmp = member.Type; memberType = Nullable.GetUnderlyingType(tmp) ?? tmp; allowNull = !(memberType.IsValueType && memberType == tmp); // but keep checking, in case of duplicates } else { memberType = null; // duplicate found; say nothing break; } } } this.allowNull[i] = allowNull; this.effectiveTypes[i] = memberType ?? typeof(object); } } else if (allMembers) { throw new InvalidOperationException("Member information is not available for this type; the required members must be specified explicitly"); } this.current = null; this.memberNames = (string[])members.Clone(); this.source = source.GetEnumerator(); }