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