コード例 #1
0
ファイル: MDStatics.cs プロジェクト: Meister1593/MDFramework
        /// <summary>
        /// Looks up the MethodInfo in our cache, if it does not exist it is resolved
        /// </summary>
        /// <param name="Node">The node to look this up for</param>
        /// <param name="Method">The name of the method</param>
        /// <param name="Parameters">The parameters you intend to send to the method</param>
        /// <returns>The MethodInfo or null if it does not exist</returns>
        public static MethodInfo GetMethodInfo(Node Node, string Method, params object[] Parameters)
        {
            Type          nodeType        = Node.GetType();
            List <Type>   Signature       = MDStatics.GetSignatureFromParameters(Parameters);
            StringBuilder SignatureString = new StringBuilder();

            Signature.ForEach(type => SignatureString.Append(type.ToString()));

            String key = $"{nodeType.ToString()}#{Method}#{SignatureString.ToString()}";

            if (!MethodInfoCache.ContainsKey(key))
            {
                MethodInfo newInfo = nodeType.GetMethod(Method, MDStatics.BindFlagsAllMembers, null, Signature.ToArray(), null);
                if (newInfo != null)
                {
                    MethodInfoCache.Add(key, newInfo);
                }
                else
                {
                    // Couldn't find anything with direct compare so we will search for the method manually and cache it if found
                    MethodInfo[] Methods = nodeType.GetAllMethods();
                    foreach (MethodInfo CandidateMethod in Methods)
                    {
                        if (CandidateMethod.Name != Method)
                        {
                            continue;
                        }

                        ParameterInfo[] CandidateParams = CandidateMethod.GetParameters();
                        if (CandidateParams.Count() != Signature.Count)
                        {
                            continue;
                        }

                        List <Type> CandidateSignature = new List <Type>();
                        CandidateParams.ToList().ForEach(param => CandidateSignature.Add(param.ParameterType));

                        MDLog.Debug(LOG_CAT, $"Evaluating {CandidateMethod.Name} ({GetParametersAsString(CandidateSignature.ToArray())})");

                        bool IsCompatible = true;

                        for (int i = 0; i < Signature.Count; ++i)
                        {
                            Type SignatureType = Signature[i];
                            Type CandidateType = CandidateSignature[i];
                            bool isNullable    = CandidateType.IsNullable();
                            if ((CandidateType.IsNullable() && (Parameters == null || Parameters[i] == null)) == false &&
                                (SignatureType.IsCastableTo(CandidateType) == false))
                            {
                                MDLog.Debug(LOG_CAT, $"CandidateMethod.Name: {CandidateMethod.Name} SignatureType: {SignatureType.ToString()} does not cast to {CandidateType.ToString()}");
                                IsCompatible = false;
                                break;
                            }
                        }

                        if (IsCompatible)
                        {
                            MDLog.Debug(LOG_CAT, $"Adding compatible method key {key}");
                            MethodInfoCache.Add(key, CandidateMethod);
                        }
                    }
                }
            }

            if (MethodInfoCache.ContainsKey(key))
            {
                return(MethodInfoCache[key]);
            }
            return(null);
        }