using System; using System.Reflection; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; public class Test { class MyClass { public void MyMethod(T a, List b, List> c) {} } public static void Main() { var typesAsStr = new [] {"T", "List`1[T]", "List`1[KeyValuePair`2[T, string]]"}; var myMethods = typeof(MyClass<>) .GetMethods() .Where(m => m.Name == "MyMethod") .ToList(); MethodInfo myMethod = null; foreach (var candidate in myMethods) { var paramTypes = candidate.GetParameters().Select(m => m.ParameterType).ToArray(); bool allGood = paramTypes.Length == typesAsStr.Length; for (var i = 0 ; allGood && i != paramTypes.Length ; i++) { allGood &= MatchType(typesAsStr[i], paramTypes[i]); } if (allGood) { myMethod = candidate; break; } } Console.WriteLine("'{0}'", myMethod); } private enum TokenType { OpenBraket, CloseBraket, Comma, Tick, Identifier, Number } private class Token { public TokenType Type { get; private set; } public string Text { get; private set; } public Token(TokenType type, string text) { Type = type; Text = text; } public override string ToString() { return string.Format("{0}:{1}", Enum.GetName(typeof(TokenType), Type), Text); } } private static bool DropToken(Queue tokens, TokenType expected) { return (tokens.Count != 0) && (tokens.Dequeue().Type == expected); } private static bool ReadToken(Queue tokens, TokenType expected, out string text) { var res = (tokens.Count != 0) && (tokens.Peek().Type == expected); text = res ? tokens.Dequeue().Text : null; return res; } private static IEnumerable Tokenize(IEnumerable str) { var res = new List(); var text = new StringBuilder(); foreach (var c in str) { var pos = "[],`".IndexOf(c); if ((pos != -1 || char.IsWhiteSpace(c)) && text.Length != 0) { res.Add(new Token( char.IsDigit(text[0]) ? TokenType.Number : TokenType.Identifier , text.ToString()) ); text = new StringBuilder(); } if (pos != -1) { res.Add(new Token((TokenType)pos, c.ToString(CultureInfo.InvariantCulture))); } else if (!char.IsWhiteSpace(c)) { text.Append(c); } } if (text.Length != 0) { res.Add(new Token( char.IsDigit(text[0]) ? TokenType.Number : TokenType.Identifier , text.ToString()) ); } return res; } public static bool MatchType(string str, Type type) { var queue = new Queue(Tokenize(str)); return MatchRecursive(queue, type) && (queue.Count == 0); } private static bool MatchRecursive(Queue tokens, Type type) { string baseName; if (!ReadToken(tokens, TokenType.Identifier, out baseName)) return false; var ranks = new List(); while (type.IsArray) { ranks.Add(type.GetArrayRank()); type = type.GetElementType(); } if (type.IsGenericType) { if (!type.Name.StartsWith(baseName+"`") || !DropToken(tokens, TokenType.Tick)) return false; string numStr; int num; if (!ReadToken(tokens, TokenType.Number, out numStr) || !int.TryParse(numStr, out num) || !DropToken(tokens, TokenType.OpenBraket)) return false; var genParams = type.GetGenericArguments(); if (genParams.Length != num) return false; for (var i = 0 ; i < num ; i++) { if (i != 0 && !DropToken(tokens, TokenType.Comma)) return false; if (!MatchRecursive(tokens, genParams[i])) return false; } if (!DropToken(tokens, TokenType.CloseBraket)) return false; } foreach (var rank in ranks) { if (!DropToken(tokens, TokenType.OpenBraket)) return false; for (var i = 0 ; i != rank-1 ; i++) { if (!DropToken(tokens, TokenType.Comma)) return false; } if (!DropToken(tokens, TokenType.CloseBraket)) return false; } return type.IsGenericType || Aliases.Contains(new KeyValuePair(baseName, type)) || type.Name == baseName; } private static readonly HashSet> Aliases = new HashSet> { new KeyValuePair("bool", typeof(bool)), new KeyValuePair("byte", typeof(byte)), new KeyValuePair("sbyte", typeof(sbyte)), new KeyValuePair("char", typeof(char)), new KeyValuePair("string", typeof(string)), new KeyValuePair("short", typeof(short)), new KeyValuePair("ushort", typeof(ushort)), new KeyValuePair("int", typeof(int)), new KeyValuePair("uint", typeof(uint)), new KeyValuePair("long", typeof(long)), new KeyValuePair("ulong", typeof(ulong)), new KeyValuePair("float", typeof(float)), new KeyValuePair("double", typeof(double)), new KeyValuePair("decimal", typeof(decimal)), new KeyValuePair("void", typeof(void)), new KeyValuePair("object", typeof(object)) }; }