private Delegate CreateGetter(int index) { var colType = DataView.Schema.GetColumnType(index); var column = DataView._schema.SchemaDefn.Columns[index]; var outputType = column.IsComputed ? column.ReturnType : column.FieldInfo.FieldType; Func <int, Delegate> del; if (outputType.IsArray) { Ch.Assert(colType.IsVector); // String[] -> VBuffer<DvText> if (outputType.GetElementType() == typeof(string)) { Ch.Assert(colType.ItemType.IsText); return(CreateStringArrayToVBufferGetter(index)); } // T[] -> VBuffer<T> Ch.Assert(outputType.GetElementType() == colType.ItemType.RawType); del = CreateArrayToVBufferGetter <int>; } else if (colType.IsVector) { // VBuffer<T> -> VBuffer<T> // REVIEW: Do we care about accomodating VBuffer<string> -> VBuffer<DvText>? Ch.Assert(outputType.IsGenericType); Ch.Assert(outputType.GetGenericTypeDefinition() == typeof(VBuffer <>)); Ch.Assert(outputType.GetGenericArguments()[0] == colType.ItemType.RawType); del = CreateVBufferToVBufferDelegate <int>; } else if (colType.IsPrimitive) { if (outputType == typeof(string)) { // String -> DvText Ch.Assert(colType.IsText); return(CreateStringToTextGetter(index)); } // T -> T Ch.Assert(colType.RawType == outputType); del = CreateDirectGetter <int>; } else { // REVIEW: Is this even possible? throw Ch.ExceptNotImpl("Type '{0}' is not yet supported.", outputType.FullName); } MethodInfo meth = del.GetMethodInfo().GetGenericMethodDefinition().MakeGenericMethod(colType.ItemType.RawType); return((Delegate)meth.Invoke(this, new object[] { index })); }
private Delegate CreateGetter(int index) { var colType = DataView.Schema.GetColumnType(index); var column = DataView._schema.SchemaDefn.Columns[index]; var outputType = column.IsComputed ? column.ReturnType : column.FieldInfo.FieldType; var genericType = outputType; Func <int, Delegate> del; if (outputType.IsArray) { Ch.Assert(colType.IsVector); // String[] -> VBuffer<DvText> if (outputType.GetElementType() == typeof(string)) { Ch.Assert(colType.ItemType.IsText); return(CreateConvertingArrayGetterDelegate <String, DvText>(index, x => x == null ? DvText.NA : new DvText(x))); } else if (outputType.GetElementType() == typeof(int)) { Ch.Assert(colType.ItemType == NumberType.I4); return(CreateConvertingArrayGetterDelegate <int, DvInt4>(index, x => x)); } else if (outputType.GetElementType() == typeof(int?)) { Ch.Assert(colType.ItemType == NumberType.I4); return(CreateConvertingArrayGetterDelegate <int?, DvInt4>(index, x => x ?? DvInt4.NA)); } else if (outputType.GetElementType() == typeof(long)) { Ch.Assert(colType.ItemType == NumberType.I8); return(CreateConvertingArrayGetterDelegate <long, DvInt8>(index, x => x)); } else if (outputType.GetElementType() == typeof(long?)) { Ch.Assert(colType.ItemType == NumberType.I8); return(CreateConvertingArrayGetterDelegate <long?, DvInt8>(index, x => x ?? DvInt8.NA)); } else if (outputType.GetElementType() == typeof(short)) { Ch.Assert(colType.ItemType == NumberType.I2); return(CreateConvertingArrayGetterDelegate <short, DvInt2>(index, x => x)); } else if (outputType.GetElementType() == typeof(short?)) { Ch.Assert(colType.ItemType == NumberType.I2); return(CreateConvertingArrayGetterDelegate <short?, DvInt2>(index, x => x ?? DvInt2.NA)); } else if (outputType.GetElementType() == typeof(sbyte)) { Ch.Assert(colType.ItemType == NumberType.I1); return(CreateConvertingArrayGetterDelegate <sbyte, DvInt1>(index, x => x)); } else if (outputType.GetElementType() == typeof(sbyte?)) { Ch.Assert(colType.ItemType == NumberType.I1); return(CreateConvertingArrayGetterDelegate <sbyte?, DvInt1>(index, x => x ?? DvInt1.NA)); } else if (outputType.GetElementType() == typeof(bool)) { Ch.Assert(colType.ItemType.IsBool); return(CreateConvertingArrayGetterDelegate <bool, DvBool>(index, x => x)); } else if (outputType.GetElementType() == typeof(bool?)) { Ch.Assert(colType.ItemType.IsBool); return(CreateConvertingArrayGetterDelegate <bool?, DvBool>(index, x => x ?? DvBool.NA)); } // T[] -> VBuffer<T> if (outputType.GetElementType().IsGenericType&& outputType.GetElementType().GetGenericTypeDefinition() == typeof(Nullable <>)) { Ch.Assert(Nullable.GetUnderlyingType(outputType.GetElementType()) == colType.ItemType.RawType); } else { Ch.Assert(outputType.GetElementType() == colType.ItemType.RawType); } del = CreateDirectArrayGetterDelegate <int>; genericType = outputType.GetElementType(); } else if (colType.IsVector) { // VBuffer<T> -> VBuffer<T> // REVIEW: Do we care about accomodating VBuffer<string> -> VBuffer<DvText>? Ch.Assert(outputType.IsGenericType); Ch.Assert(outputType.GetGenericTypeDefinition() == typeof(VBuffer <>)); Ch.Assert(outputType.GetGenericArguments()[0] == colType.ItemType.RawType); del = CreateDirectVBufferGetterDelegate <int>; genericType = colType.ItemType.RawType; } else if (colType.IsPrimitive) { if (outputType == typeof(string)) { // String -> DvText Ch.Assert(colType.IsText); return(CreateConvertingGetterDelegate <String, DvText>(index, x => x == null ? DvText.NA : new DvText(x))); } else if (outputType == typeof(bool)) { // Bool -> DvBool Ch.Assert(colType.IsBool); return(CreateConvertingGetterDelegate <bool, DvBool>(index, x => x)); } else if (outputType == typeof(bool?)) { // Bool? -> DvBool Ch.Assert(colType.IsBool); return(CreateConvertingGetterDelegate <bool?, DvBool>(index, x => x ?? DvBool.NA)); } else if (outputType == typeof(int)) { // int -> DvInt4 Ch.Assert(colType == NumberType.I4); return(CreateConvertingGetterDelegate <int, DvInt4>(index, x => x)); } else if (outputType == typeof(int?)) { // int? -> DvInt4 Ch.Assert(colType == NumberType.I4); return(CreateConvertingGetterDelegate <int?, DvInt4>(index, x => x ?? DvInt4.NA)); } else if (outputType == typeof(short)) { // short -> DvInt2 Ch.Assert(colType == NumberType.I2); return(CreateConvertingGetterDelegate <short, DvInt2>(index, x => x)); } else if (outputType == typeof(short?)) { // short? -> DvInt2 Ch.Assert(colType == NumberType.I2); return(CreateConvertingGetterDelegate <short?, DvInt2>(index, x => x ?? DvInt2.NA)); } else if (outputType == typeof(long)) { // long -> DvInt8 Ch.Assert(colType == NumberType.I8); return(CreateConvertingGetterDelegate <long, DvInt8>(index, x => x)); } else if (outputType == typeof(long?)) { // long? -> DvInt8 Ch.Assert(colType == NumberType.I8); return(CreateConvertingGetterDelegate <long?, DvInt8>(index, x => x ?? DvInt8.NA)); } else if (outputType == typeof(sbyte)) { // sbyte -> DvInt1 Ch.Assert(colType == NumberType.I1); return(CreateConvertingGetterDelegate <sbyte, DvInt1>(index, x => x)); } else if (outputType == typeof(sbyte?)) { // sbyte? -> DvInt1 Ch.Assert(colType == NumberType.I1); return(CreateConvertingGetterDelegate <sbyte?, DvInt1>(index, x => x ?? DvInt1.NA)); } // T -> T if (outputType.IsGenericType && outputType.GetGenericTypeDefinition() == typeof(Nullable <>)) { Ch.Assert(colType.RawType == Nullable.GetUnderlyingType(outputType)); } else { Ch.Assert(colType.RawType == outputType); } del = CreateDirectGetterDelegate <int>; } else { // REVIEW: Is this even possible? throw Ch.ExceptNotImpl("Type '{0}' is not yet supported.", outputType.FullName); } MethodInfo meth = del.GetMethodInfo().GetGenericMethodDefinition().MakeGenericMethod(genericType); return((Delegate)meth.Invoke(this, new object[] { index })); }
private Delegate CreateGetter(int index) { var colType = DataView.Schema.GetColumnType(index); var column = DataView._schema.SchemaDefn.Columns[index]; var outputType = column.OutputType; var genericType = outputType; Func <int, Delegate> del; if (outputType.IsArray) { Ch.Assert(colType.IsVector); // String[] -> ReadOnlyMemory<char> if (outputType.GetElementType() == typeof(string)) { Ch.Assert(colType.ItemType.IsText); return(CreateConvertingArrayGetterDelegate <string, ReadOnlyMemory <char> >(index, x => x != null ? x.AsMemory() : ReadOnlyMemory <char> .Empty)); } // T[] -> VBuffer<T> if (outputType.GetElementType().IsGenericType&& outputType.GetElementType().GetGenericTypeDefinition() == typeof(Nullable <>)) { Ch.Assert(Nullable.GetUnderlyingType(outputType.GetElementType()) == colType.ItemType.RawType); } else { Ch.Assert(outputType.GetElementType() == colType.ItemType.RawType); } del = CreateDirectArrayGetterDelegate <int>; genericType = outputType.GetElementType(); } else if (colType.IsVector) { // VBuffer<T> -> VBuffer<T> // REVIEW: Do we care about accomodating VBuffer<string> -> ReadOnlyMemory<char>? Ch.Assert(outputType.IsGenericType); Ch.Assert(outputType.GetGenericTypeDefinition() == typeof(VBuffer <>)); Ch.Assert(outputType.GetGenericArguments()[0] == colType.ItemType.RawType); del = CreateDirectVBufferGetterDelegate <int>; genericType = colType.ItemType.RawType; } else if (colType.IsPrimitive) { if (outputType == typeof(string)) { // String -> ReadOnlyMemory<char> Ch.Assert(colType.IsText); return(CreateConvertingGetterDelegate <String, ReadOnlyMemory <char> >(index, x => x != null ? x.AsMemory() : ReadOnlyMemory <char> .Empty)); } // T -> T if (outputType.IsGenericType && outputType.GetGenericTypeDefinition() == typeof(Nullable <>)) { Ch.Assert(colType.RawType == Nullable.GetUnderlyingType(outputType)); } else { Ch.Assert(colType.RawType == outputType); } del = CreateDirectGetterDelegate <int>; } else { // REVIEW: Is this even possible? throw Ch.ExceptNotImpl("Type '{0}' is not yet supported.", outputType.FullName); } MethodInfo meth = del.GetMethodInfo().GetGenericMethodDefinition().MakeGenericMethod(genericType); return((Delegate)meth.Invoke(this, new object[] { index })); }