AttachedPropertyMethodSelector.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Base / MS / Internal / ComponentModel / AttachedPropertyMethodSelector.cs / 1 / AttachedPropertyMethodSelector.cs

                             
namespace MS.Internal.ComponentModel
{
    using System;
    using System.Collections.Generic; 
    using System.ComponentModel;
    using System.Diagnostics; 
    using System.Globalization; 
    using System.Reflection;
    using System.Security.Permissions; 
    using System.Windows;

    /// 
    ///     This is a reflection binder that is used to 
    ///     find the right method match for attached properties.
    ///     The default binder in the CLR will not find a 
    ///     method match unless the parameters we provide are 
    ///     exact matches.  This binder will use compatible type
    ///     matching to find a match for any parameters that are 
    ///     compatible.
    /// 
    internal class AttachedPropertyMethodSelector : Binder
    { 

        ///  
        ///     The only method we implement.  Our goal here is to find a method that best matches the arguments passed. 
        ///     We are doing this only with the intent of pulling attached property metadata off of the method.
        ///     If there are ambiguous methods, we simply take the first one as all "Get" methods for an attached 
        ///     property should have identical metadata.
        /// 
        public override MethodBase SelectMethod(BindingFlags bindingAttr, MethodBase[] match, Type[] types, ParameterModifier[] modifiers)
        { 
            // Short circuit for cases where someone didn't pass in a types array.
            if (types == null) 
            { 
                if (match.Length > 1)
                { 
                    throw new AmbiguousMatchException();
                }
                else
                { 
                    return match[0];
                } 
            } 

            for(int idx = 0; idx < match.Length; idx++) 
            {
                MethodBase candidate = match[idx];
                ParameterInfo[] parameters = candidate.GetParameters();
                if (ParametersMatch(parameters, types)) 
                {
                    return candidate; 
                } 
            }
 
            return null;
        }

        ///  
        ///     This method checks that the parameters passed in are
        ///     compatible with the provided parameter types. 
        ///  
        private static bool ParametersMatch(ParameterInfo[] parameters, Type[] types)
        { 
            if (parameters.Length != types.Length)
            {
                return false;
            } 

            // IsAssignableFrom is not cheap.  Do this in two passes. 
            // Our first pass checks for exact type matches.  Only on 
            // the second pass do we do an IsAssignableFrom.
 
            bool compat = true;
            for(int idx = 0; idx < parameters.Length; idx++)
            {
                ParameterInfo p = parameters[idx]; 
                Type t = types[idx];
 
                if (p.ParameterType != t) 
                {
                    compat = false; 
                    break;
                }
            }
 
            if (compat)
            { 
                return true; 
            }
 
            // Second pass uses IsAssignableFrom to check for compatible types.
            compat = true;
            for(int idx = 0; idx < parameters.Length; idx++)
            { 
                ParameterInfo p = parameters[idx];
                Type t = types[idx]; 
 
                if (!t.IsAssignableFrom(p.ParameterType))
                { 
                    compat = false;
                    break;
                }
            } 

            return compat; 
        } 

        ///  
        ///     We do not implement this.
        /// 
        public override MethodBase BindToMethod(BindingFlags bindingAttr, MethodBase[] match, ref object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] names, out object state)
        { 
            // We are only a method binder.
            throw new NotImplementedException(); 
        } 

        ///  
        ///     We do not implement this.
        /// 
        public override FieldInfo BindToField(BindingFlags bindingAttr, FieldInfo[] match, object value, CultureInfo culture)
        { 
            // We are only a method binder.
            throw new NotImplementedException(); 
        } 

 
        /// 
        ///     We do not implement this.
        /// 
        public override object ChangeType(object value, Type type, CultureInfo culture) 
        {
            // We are only a method binder. 
            throw new NotImplementedException(); 
        }
 
        /// 
        ///     We do not implement this.
        /// 
        public override void ReorderArgumentArray(ref object[] args, object state) 
        {
            // We are only a method binder. 
            throw new NotImplementedException(); 
        }
 
        /// 
        ///     We do not implement this.
        /// 
        public override PropertyInfo SelectProperty(BindingFlags bindingAttr, PropertyInfo[] match, Type returnType, Type[] indexes, ParameterModifier[] modifiers) 
        {
            // We are only a method binder. 
            throw new NotImplementedException(); 
        }
    } 
}


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
 
namespace MS.Internal.ComponentModel
{
    using System;
    using System.Collections.Generic; 
    using System.ComponentModel;
    using System.Diagnostics; 
    using System.Globalization; 
    using System.Reflection;
    using System.Security.Permissions; 
    using System.Windows;

    /// 
    ///     This is a reflection binder that is used to 
    ///     find the right method match for attached properties.
    ///     The default binder in the CLR will not find a 
    ///     method match unless the parameters we provide are 
    ///     exact matches.  This binder will use compatible type
    ///     matching to find a match for any parameters that are 
    ///     compatible.
    /// 
    internal class AttachedPropertyMethodSelector : Binder
    { 

        ///  
        ///     The only method we implement.  Our goal here is to find a method that best matches the arguments passed. 
        ///     We are doing this only with the intent of pulling attached property metadata off of the method.
        ///     If there are ambiguous methods, we simply take the first one as all "Get" methods for an attached 
        ///     property should have identical metadata.
        /// 
        public override MethodBase SelectMethod(BindingFlags bindingAttr, MethodBase[] match, Type[] types, ParameterModifier[] modifiers)
        { 
            // Short circuit for cases where someone didn't pass in a types array.
            if (types == null) 
            { 
                if (match.Length > 1)
                { 
                    throw new AmbiguousMatchException();
                }
                else
                { 
                    return match[0];
                } 
            } 

            for(int idx = 0; idx < match.Length; idx++) 
            {
                MethodBase candidate = match[idx];
                ParameterInfo[] parameters = candidate.GetParameters();
                if (ParametersMatch(parameters, types)) 
                {
                    return candidate; 
                } 
            }
 
            return null;
        }

        ///  
        ///     This method checks that the parameters passed in are
        ///     compatible with the provided parameter types. 
        ///  
        private static bool ParametersMatch(ParameterInfo[] parameters, Type[] types)
        { 
            if (parameters.Length != types.Length)
            {
                return false;
            } 

            // IsAssignableFrom is not cheap.  Do this in two passes. 
            // Our first pass checks for exact type matches.  Only on 
            // the second pass do we do an IsAssignableFrom.
 
            bool compat = true;
            for(int idx = 0; idx < parameters.Length; idx++)
            {
                ParameterInfo p = parameters[idx]; 
                Type t = types[idx];
 
                if (p.ParameterType != t) 
                {
                    compat = false; 
                    break;
                }
            }
 
            if (compat)
            { 
                return true; 
            }
 
            // Second pass uses IsAssignableFrom to check for compatible types.
            compat = true;
            for(int idx = 0; idx < parameters.Length; idx++)
            { 
                ParameterInfo p = parameters[idx];
                Type t = types[idx]; 
 
                if (!t.IsAssignableFrom(p.ParameterType))
                { 
                    compat = false;
                    break;
                }
            } 

            return compat; 
        } 

        ///  
        ///     We do not implement this.
        /// 
        public override MethodBase BindToMethod(BindingFlags bindingAttr, MethodBase[] match, ref object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] names, out object state)
        { 
            // We are only a method binder.
            throw new NotImplementedException(); 
        } 

        ///  
        ///     We do not implement this.
        /// 
        public override FieldInfo BindToField(BindingFlags bindingAttr, FieldInfo[] match, object value, CultureInfo culture)
        { 
            // We are only a method binder.
            throw new NotImplementedException(); 
        } 

 
        /// 
        ///     We do not implement this.
        /// 
        public override object ChangeType(object value, Type type, CultureInfo culture) 
        {
            // We are only a method binder. 
            throw new NotImplementedException(); 
        }
 
        /// 
        ///     We do not implement this.
        /// 
        public override void ReorderArgumentArray(ref object[] args, object state) 
        {
            // We are only a method binder. 
            throw new NotImplementedException(); 
        }
 
        /// 
        ///     We do not implement this.
        /// 
        public override PropertyInfo SelectProperty(BindingFlags bindingAttr, PropertyInfo[] match, Type returnType, Type[] indexes, ParameterModifier[] modifiers) 
        {
            // We are only a method binder. 
            throw new NotImplementedException(); 
        }
    } 
}


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK