public ObjectReader(Type type, IEnumerable source, params string[] members) { if (source == null) { throw new ArgumentOutOfRangeException(nameof(source)); } var noMemberParams = members == null || members.Length == 0; _accessor = TypeAccessor.Create(type); if (_accessor.GetMembersSupported) { // Sort members by ordinal first and then by name. var typeMembers = _accessor .GetMembers() .OrderBy(p => p.Ordinal) .ToList(); if (noMemberParams) { members = new string[typeMembers.Count]; for (int i = 0; i < members.Length; i++) { members[i] = typeMembers[i].Name; } } _allowNull = new BitArray(members.Length); _effectiveTypes = new Type[members.Length]; for (int i = 0; i < members.Length; i++) { Type memberType = null; var allowNull = true; var 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; } } } _allowNull[i] = allowNull; _effectiveTypes[i] = memberType ?? typeof(object); } } else if (noMemberParams) { throw new InvalidOperationException("Member information is not available for this type; the required members must be specified explicitly"); } _current = null; _memberNames = (string[])members.Clone(); _source = source.GetEnumerator(); }