Beispiel #1
0
        /// <summary>
        /// Binds a name to type.
        /// </summary>
        /// <param name="typeName">The name of the type to bind.</param>
        /// <param name="debugContext">The debug context to log to.</param>
        /// <returns>
        /// The type that the name has been bound to, or null if the type could not be resolved.
        /// </returns>
        /// <exception cref="System.ArgumentNullException">The typeName argument is null.</exception>
        public override Type BindToType(string typeName, DebugContext debugContext = null)
        {
            if (typeName == null)
            {
                throw new ArgumentNullException("typeName");
            }

            RegisterAllQueuedAssembliesRepeating();

            Type result;

            lock (NAMETOTYPE_LOCK)
            {
                if (typeMap.TryGetValue(typeName, out result) == false)
                {
                    result = this.ParseTypeName(typeName, debugContext);

                    if (result == null && debugContext != null)
                    {
                        debugContext.LogWarning("Failed deserialization type lookup for type name '" + typeName + "'.");
                    }

                    // We allow null values on purpose so we don't have to keep re-performing invalid name lookups
                    typeMap.Add(typeName, result);
                }
            }

            return(result);
        }
Beispiel #2
0
        private Type ParseGenericAndOrArrayType(string typeName, DebugContext debugContext)
        {
            string        actualTypeName;
            List <string> genericArgNames;

            bool isGeneric;
            bool isArray;
            int  arrayRank;

            if (!TryParseGenericAndOrArrayTypeName(typeName, out actualTypeName, out isGeneric, out genericArgNames, out isArray, out arrayRank))
            {
                return(null);
            }

            Type type = this.BindToType(actualTypeName, debugContext);

            if (type == null)
            {
                return(null);
            }

            if (isGeneric)
            {
                if (!type.IsGenericType)
                {
                    return(null);
                }

                using (var argsCache = Cache <List <Type> > .Claim())
                {
                    List <Type> args = argsCache.Value;
                    args.Clear();

                    for (int i = 0; i < genericArgNames.Count; i++)
                    {
                        Type arg = this.BindToType(genericArgNames[i], debugContext);
                        if (arg == null)
                        {
                            return(null);
                        }
                        args.Add(arg);
                    }

                    var argsArray = args.ToArray();

                    if (!type.AreGenericConstraintsSatisfiedBy(argsArray))
                    {
                        if (debugContext != null)
                        {
                            string argsStr = "";

                            foreach (var arg in argsArray)
                            {
                                if (argsStr != "")
                                {
                                    argsStr += ", ";
                                }
                                argsStr += arg.GetNiceFullName();
                            }

                            debugContext.LogWarning("Deserialization type lookup failure: The generic type arguments '" + argsStr + "' do not satisfy the generic constraints of generic type definition '" + type.GetNiceFullName() + "'. All this parsed from the full type name string: '" + typeName + "'");
                        }

                        return(null);
                    }

                    type = type.MakeGenericType(argsArray);
                    args.Clear();
                }
            }

            if (isArray)
            {
                if (arrayRank == 1)
                {
                    type = type.MakeArrayType();
                }
                else
                {
                    type = type.MakeArrayType(arrayRank);
                }
            }

            return(type);
        }