예제 #1
0
        /// <summary>
        /// Walk over a type to create a value.
        /// </summary>
        /// <param name="visitor">The type visitor object.</param>
        /// <param name="type">The type.</param>
        /// <typeparam name="T">The return type.</typeparam>
        /// <returns>A value.</returns>
        internal static T ApplyTypeVisitor <T>(ITypeVisitor <T> visitor, Type type)
        {
            if (type == BoolType)
            {
                return(visitor.VisitBool());
            }
            if (type == ByteType)
            {
                return(visitor.VisitByte());
            }
            if (type == ShortType)
            {
                return(visitor.VisitShort());
            }
            if (type == UshortType)
            {
                return(visitor.VisitUshort());
            }
            if (type == IntType)
            {
                return(visitor.VisitInt());
            }
            if (type == UintType)
            {
                return(visitor.VisitUint());
            }
            if (type == LongType)
            {
                return(visitor.VisitLong());
            }
            if (type == UlongType)
            {
                return(visitor.VisitUlong());
            }
            if (type == BigIntType)
            {
                return(visitor.VisitBigInteger());
            }
            if (type == StringType)
            {
                return(visitor.VisitString());
            }
            if (IsFixedIntegerType(type))
            {
                return(visitor.VisitFixedInteger(type));
            }

            if (IsOptionType(type))
            {
                var t = type.GetGenericArguments()[0];
                return(visitor.VisitOption(ty => ApplyTypeVisitor(visitor, ty), type, t));
            }

            if (IsTupleType(type))
            {
                var tleft  = type.GetGenericArguments()[0];
                var tright = type.GetGenericArguments()[1];
                return(visitor.VisitTuple(ty => ApplyTypeVisitor(visitor, ty), type, tleft, tright));
            }

            if (IsValueTupleType(type))
            {
                var tleft  = type.GetGenericArguments()[0];
                var tright = type.GetGenericArguments()[1];
                return(visitor.VisitValueTuple(ty => ApplyTypeVisitor(visitor, ty), type, tleft, tright));
            }

            if (IsIListType(type))
            {
                var t = type.GetGenericArguments()[0];
                return(visitor.VisitList(ty => ApplyTypeVisitor(visitor, ty), type, t));
            }

            if (IsIDictionaryType(type))
            {
                var args   = type.GetGenericArguments();
                var tkey   = args[0];
                var tvalue = args[1];
                return(visitor.VisitDictionary(ty => ApplyTypeVisitor(visitor, ty), type, tkey, tvalue));
            }

            if (IsListType(type) || IsDictionaryType(type))
            {
                throw new InvalidOperationException($"Unsupported object field type: {type}");
            }

            // some class or struct
            var dict = new SortedDictionary <string, Type>();

            foreach (var field in GetAllFields(type))
            {
                dict[field.Name] = field.FieldType;
            }

            foreach (var property in GetAllProperties(type))
            {
                dict[property.Name] = property.PropertyType;
            }

            return(visitor.VisitObject(t => ApplyTypeVisitor(visitor, t), type, dict));
        }