Ejemplo n.º 1
0
        /// <summary>
        /// Each of the specialized 'peek' methods copies the appropriate field value of an instance of T
        /// into the provided buffer. So, the call is 'peek(userObject, ref destination)' and the logic is
        /// indentical to 'destination = userObject.##FIELD##', where ##FIELD## is defined per peek method.
        /// </summary>
        internal static Delegate GeneratePeek <TOwn, TRow>(InternalSchemaDefinition.Column column)
        {
            switch (column.MemberInfo)
            {
            case FieldInfo fieldInfo:
                Type fieldType = fieldInfo.FieldType;

                var assignmentOpCode = GetAssignmentOpCode(fieldType);
                Func <FieldInfo, OpCode, Delegate> func = GeneratePeek <TOwn, TRow, int>;
                var methInfo = func.GetMethodInfo().GetGenericMethodDefinition()
                               .MakeGenericMethod(typeof(TOwn), typeof(TRow), fieldType);
                return((Delegate)methInfo.Invoke(null, new object[] { fieldInfo, assignmentOpCode }));

            case PropertyInfo propertyInfo:
                Type propertyType = propertyInfo.PropertyType;

                var assignmentOpCodeProp = GetAssignmentOpCode(propertyType);
                Func <PropertyInfo, OpCode, Delegate> funcProp = GeneratePeek <TOwn, TRow, int>;
                var methInfoProp = funcProp.GetMethodInfo().GetGenericMethodDefinition()
                                   .MakeGenericMethod(typeof(TOwn), typeof(TRow), propertyType);
                return((Delegate)methInfoProp.Invoke(null, new object[] { propertyInfo, assignmentOpCodeProp }));

            default:
                Contracts.Assert(false);
                throw Contracts.ExceptNotSupp("Expected a FieldInfo or a PropertyInfo");
            }
        }
Ejemplo n.º 2
0
        private static OpCode GetAssignmentOpCode(Type t)
        {
            // REVIEW: This should be a Dictionary<Type, OpCode> based solution.
            // DvTypes, strings, arrays, all nullable types, VBuffers and RowId.
            if (t == typeof(ReadOnlyMemory <char>) || t == typeof(string) || t.IsArray ||
                (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(VBuffer <>)) ||
                (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable <>)) ||
                t == typeof(DateTime) || t == typeof(DateTimeOffset) || t == typeof(TimeSpan) || t == typeof(RowId))
            {
                return(OpCodes.Stobj);
            }

            // Simple primitive types.
            if (t == typeof(Single))
            {
                return(OpCodes.Stind_R4);
            }
            if (t == typeof(Double))
            {
                return(OpCodes.Stind_R8);
            }
            if (t == typeof(sbyte) || t == typeof(byte) || t == typeof(bool))
            {
                return(OpCodes.Stind_I1);
            }
            if (t == typeof(short) || t == typeof(ushort))
            {
                return(OpCodes.Stind_I2);
            }
            if (t == typeof(int) || t == typeof(uint))
            {
                return(OpCodes.Stind_I4);
            }
            if (t == typeof(long) || t == typeof(ulong))
            {
                return(OpCodes.Stind_I8);
            }
            throw Contracts.ExceptNotSupp("Type '{0}' is not supported.", t.FullName);
        }