Как вызвать универсальный метод во время выполнения безопасным способом - PullRequest
0 голосов
/ 06 апреля 2019

Я пытаюсь вызвать универсальный метод во время выполнения, и у меня есть рабочий код. Тем не менее, мне было интересно, если есть лучший способ получить информацию о методе, как я должен изменить имя метода, он сломается.

public int Handle<T>(CreateCodeModel obj) where T : CodeModel
{
     //Create code here...
}

//codeType is selected by user.
public int Handle(CreateCodeModel obj, Type codeType)
{

    MethodInfo method = this.GetType().GetMethod("Handle");
    //MethodInfo method = this.GetType().GetMethods()
            .Where(mi => mi.IsGenericMethod && mi.Name == "Handle").First();

    MethodInfo genericMethod = method.MakeGenericMethod(new Type[] { codeType });
    return (int)genericMethod.Invoke(this, new object[] { obj });

}

Я надеялся, что есть более хороший способ сделать это, возможно, с помощью действий, чтобы получить информацию о методе, но тогда мне все еще нужно предоставить тип, например,

Action<CreateCodeModel> h = (x) => Handle(x);
MethodInfo method = h.Method;

1 Ответ

0 голосов
/ 07 апреля 2019

Вы находитесь на правильном пути здесь.Ваша подпись делегата должна соответствовать методу, который вы вызываете, поэтому в этом случае это будет Func<CreateCodeModel,int> вместо Action<CreateCodeModel>.И вы должны предоставить общий параметр, который соответствует общим ограничениям.Это может быть что угодно, так как мы просто удалим его с помощью нашего вызова GetGenericMethodDefinition, но мне нравится использовать класс из ограничения.

Другой фрагмент кода ниже - это идея, которая вам нужна толькочтобы получить определение универсального метода один раз, поскольку оно не изменяется, поэтому я сохраняю его в статической переменной, чтобы его можно было повторно использовать.

public int Handle<T>(CreateCodeModel obj) where T : CodeModel
{
    //Create code here...
    return 7;
}

// this static variable preserves the generic MethodInfo, so we don't have
// keep discovering it with reflection
private static MethodInfo _methodInfoForHandle;

// The generic MethodInfo only needs to be discovered the first time this runs
private MethodInfo MethodInfoForHandle
{
    get
    {
        return _methodInfoForHandle ?? (_methodInfoForHandle = GetMethodInfoForHandleMethod());
    }
}

private MethodInfo GetMethodInfoForHandleMethod()
{
    Func<CreateCodeModel, int> handleFunc = Handle<CodeModel>;
    return handleFunc.Method.GetGenericMethodDefinition();
}


//codeType is selected by user.
public int Handle(CreateCodeModel obj, Type codeType)
{
    MethodInfo genericMethod = MethodInfoForHandle.MakeGenericMethod(new Type[] { codeType });
    return (int)genericMethod.Invoke(this, new object[] { obj });

}

public class CreateCodeModel { }
public class CodeModel { }
public class JavascriptCodeModel : CodeModel { }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...