private Action <TRow> GenerateSetter(Row input, int index, InternalSchemaDefinition.Column column, Delegate poke, Delegate peek)
            {
                var colType     = input.Schema[index].Type;
                var fieldType   = column.OutputType;
                var genericType = fieldType;
                Func <Row, int, Delegate, Delegate, Action <TRow> > del;

                if (fieldType.IsArray)
                {
                    Ch.Assert(colType is VectorType);
                    // VBuffer<ReadOnlyMemory<char>> -> String[]
                    if (fieldType.GetElementType() == typeof(string))
                    {
                        Ch.Assert(colType.GetItemType() is TextType);
                        return(CreateConvertingVBufferSetter <ReadOnlyMemory <char>, string>(input, index, poke, peek, x => x.ToString()));
                    }

                    // VBuffer<T> -> T[]
                    if (fieldType.GetElementType().IsGenericType&& fieldType.GetElementType().GetGenericTypeDefinition() == typeof(Nullable <>))
                    {
                        Ch.Assert(colType.GetItemType().RawType == Nullable.GetUnderlyingType(fieldType.GetElementType()));
                    }
                    else
                    {
                        Ch.Assert(colType.GetItemType().RawType == fieldType.GetElementType());
                    }
                    del         = CreateDirectVBufferSetter <int>;
                    genericType = fieldType.GetElementType();
                }
                else if (colType is VectorType vectorType)
                {
                    // VBuffer<T> -> VBuffer<T>
                    // REVIEW: Do we care about accomodating VBuffer<string> -> VBuffer<ReadOnlyMemory<char>>?
                    Ch.Assert(fieldType.IsGenericType);
                    Ch.Assert(fieldType.GetGenericTypeDefinition() == typeof(VBuffer <>));
                    Ch.Assert(fieldType.GetGenericArguments()[0] == vectorType.ItemType.RawType);
                    del         = CreateVBufferToVBufferSetter <int>;
                    genericType = vectorType.ItemType.RawType;
                }
                else if (colType is PrimitiveType)
                {
                    if (fieldType == typeof(string))
                    {
                        // ReadOnlyMemory<char> -> String
                        Ch.Assert(colType is TextType);
                        Ch.Assert(peek == null);
                        return(CreateConvertingActionSetter <ReadOnlyMemory <char>, string>(input, index, poke, x => x.ToString()));
                    }

                    // T -> T
                    if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Nullable <>))
                    {
                        Ch.Assert(colType.RawType == Nullable.GetUnderlyingType(fieldType));
                    }
                    else
                    {
                        Ch.Assert(colType.RawType == fieldType);
                    }

                    del = CreateDirectSetter <int>;
                }
                else
                {
                    // REVIEW: Is this even possible?
                    throw Ch.ExceptNotImpl("Type '{0}' is not yet supported.", column.OutputType.FullName);
                }
                MethodInfo meth = del.GetMethodInfo().GetGenericMethodDefinition().MakeGenericMethod(genericType);

                return((Action <TRow>)meth.Invoke(this, new object[] { input, index, poke, peek }));
            }
            //private Delegate CreateGetter(SchemaProxy schema, int index, Delegate peek)
            private Delegate CreateGetter(DataViewType colType, InternalSchemaDefinition.Column column, Delegate peek)
            {
                var outputType  = column.OutputType;
                var genericType = outputType;
                Func <Delegate, Delegate> del;

                if (outputType.IsArray)
                {
                    VectorType vectorType = colType as VectorType;
                    Host.Assert(vectorType != null);

                    // String[] -> ReadOnlyMemory<char>
                    if (outputType.GetElementType() == typeof(string))
                    {
                        Host.Assert(vectorType.ItemType is TextDataViewType);
                        return(CreateConvertingArrayGetterDelegate <string, ReadOnlyMemory <char> >(peek, x => x != null ? x.AsMemory() : ReadOnlyMemory <char> .Empty));
                    }

                    // T[] -> VBuffer<T>
                    if (outputType.GetElementType().IsGenericType&& outputType.GetElementType().GetGenericTypeDefinition() == typeof(Nullable <>))
                    {
                        Host.Assert(Nullable.GetUnderlyingType(outputType.GetElementType()) == vectorType.ItemType.RawType);
                    }
                    else
                    {
                        Host.Assert(outputType.GetElementType() == vectorType.ItemType.RawType);
                    }
                    del         = CreateDirectArrayGetterDelegate <int>;
                    genericType = outputType.GetElementType();
                }
                else if (colType is VectorType vectorType)
                {
                    // VBuffer<T> -> VBuffer<T>
                    // REVIEW: Do we care about accomodating VBuffer<string> -> ReadOnlyMemory<char>?
                    Host.Assert(outputType.IsGenericType);
                    Host.Assert(outputType.GetGenericTypeDefinition() == typeof(VBuffer <>));
                    Host.Assert(outputType.GetGenericArguments()[0] == vectorType.ItemType.RawType);
                    del         = CreateDirectVBufferGetterDelegate <int>;
                    genericType = vectorType.ItemType.RawType;
                }
                else if (colType is PrimitiveDataViewType)
                {
                    if (outputType == typeof(string))
                    {
                        // String -> ReadOnlyMemory<char>
                        Host.Assert(colType is TextDataViewType);
                        return(CreateConvertingGetterDelegate <String, ReadOnlyMemory <char> >(peek, x => x != null ? x.AsMemory() : ReadOnlyMemory <char> .Empty));
                    }

                    // T -> T
                    if (outputType.IsGenericType && outputType.GetGenericTypeDefinition() == typeof(Nullable <>))
                    {
                        Host.Assert(colType.RawType == Nullable.GetUnderlyingType(outputType));
                    }
                    else
                    {
                        Host.Assert(colType.RawType == outputType);
                    }

                    if (!(colType is KeyType keyType))
                    {
                        del = CreateDirectGetterDelegate <int>;
                    }
                    else
                    {
                        var keyRawType = colType.RawType;
                        Func <Delegate, DataViewType, Delegate> delForKey = CreateKeyGetterDelegate <uint>;
                        return(Utils.MarshalInvoke(delForKey, keyRawType, peek, colType));
                    }
                }