private Func <IDataReader, object> GetReader(IDataReader reader, int startBound, int length, bool returnNullIfFirstMissing) { if (length < 0) { length = reader.FieldCount - startBound; } int hash = GetColumnHash(reader, startBound, length); if (returnNullIfFirstMissing) { hash *= -27; } // get a cheap key first: false means don't copy the values down var key = new DeserializerKey(hash, startBound, length, returnNullIfFirstMissing, reader, false); Func <IDataReader, object> deser; lock (readers) { if (readers.TryGetValue(key, out deser)) { return(deser); } } deser = GetTypeDeserializerImpl(type, reader, startBound, length, returnNullIfFirstMissing); // get a more expensive key: true means copy the values down so it can be used as a key later key = new DeserializerKey(hash, startBound, length, returnNullIfFirstMissing, reader, true); lock (readers) { return(readers[key] = deser); } }
private Func <XmlGridRowReader, object> GetDeserializer( XmlGridRowReader reader) { reader.ReadRow(); if (!reader.Columns.Any()) { throw new InvalidOperationException("No columns"); } var key = new DeserializerKey(reader.Columns); if (!deserializers.TryGetValue(key, out var deserializer)) { lock (deserializers) { if (!deserializers.TryGetValue(key, out deserializer)) { deserializer = CreateDeserializer(type, reader.Columns); deserializers.Add(key, deserializer); } } } return(deserializer); }
public bool Equals(DeserializerKey other) { if (hashCode != other.hashCode || startBound != other.startBound || length != other.length || returnNullIfFirstMissing != other.returnNullIfFirstMissing) { return false; // clearly different } for (int i = 0; i < length; i++) { if ((names? i] ?? reader?.GetName(startBound + i)) != (other.names? i] ?? other.reader?.GetName(startBound + i)) || (types? i] ?? reader?.GetFieldType(startBound + i)) != (other.types? i] ?? other.reader?.GetFieldType(startBound + i)) ) { return false; // different column name or type } } return true; }