Example #1
0
        /// <SecurityNote>
        /// Because this is a public virtual method, idempotence cannot be guaranteed.
        /// S.X doesn't use this method at all; but any externals consumers who are doing security checks
        /// based on the returned method should make sure that they are resillient to changing results.
        /// </SecurityNote>
        public virtual MethodInfo GetAddMethod(XamlType contentType)
        {
            if (contentType == null)
            {
                throw new ArgumentNullException(nameof(contentType));
            }
            if (IsUnknown || _xamlType.ItemType == null)
            {
                return(null);
            }

            // Common case is that we match the item type. Short-circuit any additional lookup.
            if (contentType == _xamlType.ItemType ||
                (_xamlType.AllowedContentTypes.Count == 1 && contentType.CanAssignTo(_xamlType.ItemType)))
            {
                return(_xamlType.AddMethod);
            }

            // Only collections can have additional content types
            if (!_xamlType.IsCollection)
            {
                return(null);
            }

            // Populate the dictionary of all available Add methods
            MethodInfo addMethod;

            if (_addMethods == null)
            {
                Dictionary <XamlType, MethodInfo> addMethods = new Dictionary <XamlType, MethodInfo>();
                addMethods.Add(_xamlType.ItemType, _xamlType.AddMethod);
                foreach (XamlType type in _xamlType.AllowedContentTypes)
                {
                    addMethod = CollectionReflector.GetAddMethod(
                        _xamlType.UnderlyingType, type.UnderlyingType);
                    if (addMethod != null)
                    {
                        addMethods.Add(type, addMethod);
                    }
                }
                _addMethods = addMethods;
            }

            // First try the fast path.  Look for an exact match.
            if (_addMethods.TryGetValue(contentType, out addMethod))
            {
                return(addMethod);
            }

            // Next the slow path.  Check each one for is assignable from.
            foreach (KeyValuePair <XamlType, MethodInfo> pair in _addMethods)
            {
                if (contentType.CanAssignTo(pair.Key))
                {
                    return(pair.Value);
                }
            }

            return(null);
        }
Example #2
0
 public virtual MethodInfo GetAddMethod(XamlType contentType)
 {
     if (contentType == null)
     {
         throw new ArgumentNullException("contentType");
     }
     if (!this.IsUnknown && (this._xamlType.ItemType != null))
     {
         MethodInfo addMethod;
         if ((contentType == this._xamlType.ItemType) || ((this._xamlType.AllowedContentTypes.Count == 1) && contentType.CanAssignTo(this._xamlType.ItemType)))
         {
             return(this._xamlType.AddMethod);
         }
         if (!this._xamlType.IsCollection)
         {
             return(null);
         }
         if (this._addMethods == null)
         {
             Dictionary <XamlType, MethodInfo> dictionary = new Dictionary <XamlType, MethodInfo>();
             dictionary.Add(this._xamlType.ItemType, this._xamlType.AddMethod);
             foreach (XamlType type in this._xamlType.AllowedContentTypes)
             {
                 addMethod = CollectionReflector.GetAddMethod(this._xamlType.UnderlyingType, type.UnderlyingType);
                 if (addMethod != null)
                 {
                     dictionary.Add(type, addMethod);
                 }
             }
             this._addMethods = dictionary;
         }
         if (this._addMethods.TryGetValue(contentType, out addMethod))
         {
             return(addMethod);
         }
         foreach (KeyValuePair <XamlType, MethodInfo> pair in this._addMethods)
         {
             if (contentType.CanAssignTo(pair.Key))
             {
                 return(pair.Value);
             }
         }
     }
     return(null);
 }