Как использовать отражение для получения метода расширения для универсального типа

Из различных источников в межсетях я почерпнул следующую функцию:

public static Nullable TryParseNullable(this Nullable t, string input) where T : struct
{
    if (string.IsNullOrEmpty(input))
        return default(T);

    Nullable result = new Nullable();
    try
    {
        IConvertible convertibleString = (IConvertible)input;
        result = new Nullable((T)convertibleString.ToType(typeof(T), CultureInfo.CurrentCulture));
    }
    catch (InvalidCastException) { }
    catch (FormatException) { }

    return result;
}

Я превратил ее в метод расширения, и она отлично работает, если я вызываю ее напрямую:

int? input = new int?().TryParseNullable("12345");

My проблема возникает, когда я пытаюсь вызвать его, используя отражение из контекста другой универсальной функции. SO полон ответов, описывающих, как получить MethodInfo общих методов и статических методов, но мне кажется, что я не могу правильно их собрать.
Я правильно определил, что переданный универсальный тип сам по себе является универсальным типом ( Nullable ), теперь я хочу использовать отражение для вызова метода расширения TryParseNullable на Обнуляемый :

public static T GetValue(string name, T defaultValue)
{
    string result = getSomeStringValue(name);
    if (string.IsNullOrEmpty(result)) return defaultValue;

    try
    {
        if (typeof(T).IsGenericType && typeof(T).GetGenericTypeDefinition() == typeof(Nullable<>))
        {
            MethodInfo methodInfo;

            //using the TryParse() of the underlying type works but isn't exactly the way i want to do it
            //------------------------------------------------------------------------------------------- 
            NullableConverter nc = new NullableConverter(typeof(T));
            Type t = nc.UnderlyingType;

            methodInfo = t.GetMethod("TryParse", BindingFlags.Public | BindingFlags.Static, Type.DefaultBinder, new[] { typeof(string), t.MakeByRefType() }, null);
            if (methodInfo != null)
            {
                var inputParameters = new object[] { result, null };
                methodInfo.Invoke(null, inputParameters);
                return (T) inputParameters[1];
            }

            //start of the problem area
            //-------------------------

            Type ttype = typeof(T);

            //this works but is undesirable (due to reference to class containing the static method):
            methodInfo = typeof(ParentExtensionsClass).GetMethod("TryParseNullable", BindingFlags.Public | BindingFlags.Static);
            if (methodInfo != null)
                Console.WriteLine(methodInfo);

            //standard way of getting static method, doesn't work (GetMethod() returns null):
            methodInfo = ttype.GetMethod("TryParseNullable", BindingFlags.Public | BindingFlags.Static);
            if (methodInfo != null)
                Console.WriteLine(methodInfo);

            //Jon Skeet's advised method, doesn't work in this case (again GetMethod() returns null):
            //(see footnote for link to this answer)
            methodInfo = ttype.GetMethod("TryParseNullable");
            methodInfo = methodInfo.MakeGenericMethod(ttype);
            if (methodInfo != null)
                Console.WriteLine(methodInfo);

            //another random attempt (also doesn't work):
            methodInfo = ttype.GetMethod("TryParseNullable", BindingFlags.Public | BindingFlags.Static, Type.DefaultBinder, new[] { typeof(string) }, null);
            if (methodInfo != null)
                Console.WriteLine(methodInfo);
        }

        // if we get this far, then we are not handling the type yet
        throw new ArgumentException("The type " + defaultValue.GetType() + " is not yet supported by GetValue.", "T");
    }
    catch (Exception e)
    {
        [snip]
    }
}

Может ли кто-нибудь избавить меня от моих страданий?
typeof (T) возвращает правильную информацию о типе, я полагаю, что, возможно, я использую его немного неправильно с вызовом GetMethod () , или я не указал правильный параметры с вызовом GetMethod () .

1. Ссылка на указанный ответ Джона Скита

10
задан Community 23 May 2017 в 12:12
поделиться