/// <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); }
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); }