Example #1
0
        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();
        }