public T Read <T>(SerializationCtx ctx, UnsafeReader reader, [CanBeNull] CtxReadDelegate <T> unknownInstanceReader = null) { bool TryGetReader(RdId rdId, out CtxReadDelegate <object> readDelegate) { lock (myLock) return(myReaders.TryGetValue(rdId, out readDelegate)); } #if !NET35 myBackgroundRegistrar.WaitForEmpty(); #endif var typeId = RdId.Read(reader); if (typeId.IsNil) { return(default(T)); } var size = reader.ReadInt(); if (!TryGetReader(typeId, out var ctxReadDelegate)) { if (unknownInstanceReader == null) { myRegistrar?.TryRegister(typeId, this); myRegistrar?.TryRegister(typeof(T), this); if (!TryGetReader(typeId, out ctxReadDelegate)) { var realType = myTypeMapping.SingleOrDefault(c => Equals(c.Value, typeId)); //ok because it's rarely needed throw new KeyNotFoundException(string.Format("There is no readers found. Requested type '{0}'. Real type {1}", typeof(T).FullName, realType)); } } else { var objectStart = reader.Position; var result = unknownInstanceReader(ctx, reader); var bytesRead = reader.Position - objectStart; reader.Skip(size - bytesRead); return(result); } } var uncasted = ctxReadDelegate(ctx, reader); Assertion.Assert(uncasted is T, "Bad cast for id {0}. Expected: {1}, actual: {2}", typeId, typeof(T).Name, uncasted.GetType().Name); return((T)uncasted); }