Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2020
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.27 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5.  
  6. namespace ConsoleApp
  7. {
  8.     public class MethodPattern
  9.     {
  10.         public string Name;
  11.         public Type Return;
  12.         public Type[] Parameters;
  13.     }
  14.  
  15.     public static class Reflection
  16.     {
  17.         private enum TypeRestrict { NotEqual, Strong, Generic, Inherited }
  18.  
  19.         public static MethodInfo FindInstanceMethod(Type targetType, MethodPattern pattern) =>
  20.             FindMethod(pattern, targetType.GetMethods(BindingFlags.Instance | BindingFlags.Public));
  21.         public static MethodInfo FindStaticMethod(Type targetType, MethodPattern pattern) =>
  22.             FindMethod(pattern, targetType.GetMethods(BindingFlags.Static | BindingFlags.Public));
  23.         private static MethodInfo FindMethod(MethodPattern pattern, MethodInfo[] source)
  24.         {
  25.             var methods = source.Where(m => m.Name == pattern.Name).ToArray();
  26.             if (pattern.Parameters?.Length > 0)
  27.                 methods = FilterMethodsByParameters(methods, pattern.Parameters);
  28.             if (pattern.Return != null)
  29.                 return FindMethodByReturnType(methods, pattern.Return);
  30.             return methods.FirstOrDefault();
  31.         }
  32.  
  33.         private static MethodInfo[] FilterMethodsByParameters(MethodInfo[] source, Type[] targetParameters)
  34.         {
  35.             var methodByWeight = new Dictionary<MethodInfo, int>();
  36.             foreach (var method in source)
  37.             {
  38.                 var parameters = method.GetParameters();
  39.                 if (parameters.Length != targetParameters.Length)
  40.                     continue;
  41.  
  42.                 var weight = 0;
  43.                 for (var i = 0; i < parameters.Length; i++)
  44.                 {
  45.                     var restrict = GetTypeRestrict(parameters[i].ParameterType, targetParameters[i]);
  46.                     if (restrict == TypeRestrict.NotEqual)
  47.                     {
  48.                         weight = -1;
  49.                         break;
  50.                     }
  51.                     if (restrict == TypeRestrict.Strong)
  52.                         weight += 0 + i;
  53.                     else if (restrict == TypeRestrict.Generic)
  54.                         weight += 1 + i;
  55.                     else if (restrict == TypeRestrict.Inherited)
  56.                         weight += 2 + i;
  57.                 }
  58.                 if (weight >= 0)
  59.                     methodByWeight.Add(method, weight);
  60.             }
  61.             return methodByWeight
  62.                 .OrderBy(m => m.Value)
  63.                 .Select(m => m.Key)
  64.                 .ToArray();
  65.         }
  66.         private static MethodInfo FindMethodByReturnType(MethodInfo[] source, Type returnType)
  67.         {
  68.             var methodByWeight = new Dictionary<MethodInfo, int>();
  69.             foreach (var method in source)
  70.             {
  71.                 var restrict = GetTypeRestrict(method.ReturnType, returnType);
  72.                 if (restrict == TypeRestrict.NotEqual)
  73.                     continue;
  74.  
  75.                 if (restrict == TypeRestrict.Strong)
  76.                     methodByWeight.Add(method, 0);
  77.                 else if (restrict == TypeRestrict.Generic)
  78.                     methodByWeight.Add(method, 1);
  79.                 else if (restrict == TypeRestrict.Inherited)
  80.                     methodByWeight.Add(method, 2);
  81.             }
  82.             return methodByWeight
  83.                 .OrderBy(m => m.Value)
  84.                 .Select(m => m.Key)
  85.                 .FirstOrDefault();
  86.         }
  87.  
  88.         private static TypeRestrict GetTypeRestrict(Type source, Type target)
  89.         {
  90.             if (source == target)
  91.                 return TypeRestrict.Strong;
  92.  
  93.             if (source.IsArray && target.IsArray)
  94.                 return GetTypeRestrict(source.GetElementType(), target.GetElementType());
  95.  
  96.             if (source.IsGenericParameter || source.IsGenericTypeDefinition)
  97.                 return TypeRestrict.Generic;
  98.  
  99.             if (source.IsGenericType && target.IsGenericType &&
  100.                 source.GetGenericTypeDefinition() == target.GetGenericTypeDefinition())
  101.                 return TypeRestrict.Generic;
  102.  
  103.             if (source.IsAssignableFrom(target))
  104.                 return TypeRestrict.Inherited;
  105.  
  106.             return TypeRestrict.NotEqual;
  107.         }
  108.     }
  109. }
  110.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement