Создайте вызов метода в.NET на основе строкового значения

10
задан 3 revs, 2 users 100% 25 September 2008 в 16:26
поделиться

11 ответов

Type type = GetType();
MethodInfo method = type.GetMethod("Show"+reportName+"Report");
if (method != null)
{
    method.Invoke(this, null);
}

Это - C#, должно быть достаточно легко превратить его в VB. Если необходимо передать параметр в метод, они могут быть добавлены в 2-м аргументе для Вызова.

18
ответ дан 3 December 2019 в 14:26
поделиться

API Reflection позволяет Вам получать a MethodInfo из метода, затем звоня Invoke динамично на нем. Но это - излишество в Вашем случае.

Необходимо считать наличие словаря делегатов индексированным строками.

3
ответ дан 3 December 2019 в 14:26
поделиться

У Вас есть более глубокая проблема. Ваши строки слишком важны. Кто передает, Вы представляете в виде строки? можно ли заставить их не сделать этого?

Палка с оператором переключения, поскольку это отделяет Вашу внутреннюю реализацию (имена методов) от Вашего внешнего представления.

Предположим, что Вы локализуете это немецкому языку. Вы собираетесь переименовать все те методы?

5
ответ дан 3 December 2019 в 14:26
поделиться

Используйте отражение. В System.Reflection пространство имен необходимо получить a MethodInfo объект для метода Вы хотите, с помощью GetMethod("methodName") на типе, содержащем метод.

После того как Вы имеете MethodInfo объект, можно звонить .Invoke() с экземпляром объекта и любыми параметрами.

Например:

System.Reflection.MethodInfo method = this.GetType().GetMethod("foo");
method.Invoke(this, null);
3
ответ дан 3 December 2019 в 14:26
поделиться

Вы могли использовать отражение, чтобы сделать это, но быть честным я думаю, что оно сверхусложняет вещи для Вашего конкретного сценария т.е. кода и переключателя () в том же классе.

Теперь, если Вы разработали приложение, чтобы иметь каждый тип отчета в его собственном блоке (своего рода как add-in/plugin архитектура) или связались в единственном внешнем блоке затем, Вы могли загрузить создание отчетов assemblie (s) в appdomain и затем использовать отражение, чтобы сделать такого рода вещь.

3
ответ дан 3 December 2019 в 14:26
поделиться

Используя отражение:

Type t = this.GetType();
try 
{
    MethodInfo mi = t.GetMethod(methodName, ...);

    if (mi != null)
    {
        mi.Invoke(this, parameters);
    }
} 

Но я соглашаюсь с назад, лучше не изменяют Ваш исходный код ;-)

0
ответ дан 3 December 2019 в 14:26
поделиться

Если я понимаю вопрос правильно, необходимо будет использовать Отражение, чтобы найти метод "шоу" + reportName и затем вызвать его косвенно:

Непродуманный пример:

Case "financial" :
{
   Assembly asm = Assembly.GetExecutingAssembly ();

    MethodInfo mi = asm.GetType ("thisClassType").GetMethod ("showFinancialReport");

   if (mi != null)
      mi.Invoke (null, new object[] {});

}

Вставьте свою собственную логику там для составления названия метода для вызова.

См. документацию MSDN MethodInfo и блока для деталей.

0
ответ дан 3 December 2019 в 14:26
поделиться

Можно использовать отражение. Хотя лично, я думаю, что необходимо просто придерживаться оператора переключения.

private void ShowReport(string methodName)
{
    Type type = this.GetType();
    MethodInfo method = type.GetMethod("Show"+methodName+"Report", BindingFlags.Public)
    method.Invoke(this, null);
}

Извините, я делаю C#. Просто переведите его в VB.NET.

2
ответ дан 3 December 2019 в 14:26
поделиться

Python (и IronPython) может сделать эту вещь очень легко. С .NET, хотя, необходимо использовать отражение.

В C#: http://www.dotnetspider.com/resources/4634-Invoke-me-ods-dynamically-using-reflection.aspx

Мой быстрый порт к VB.Net:

Private Sub InvokeMethod(instance as object, methodName as string )
            'Getting the method information using the method info class
            Dim mi as MethodInfo = instance.GetType().GetMethod(methodName)

            'invoing the method
            'null- no parameter for the function [or] we can pass the array of parameters
            mi.Invoke(instance, Nothing)
End Sub
0
ответ дан 3 December 2019 в 14:26
поделиться

Вы можете, с помощью Системы. Отражение. См. эту статью проекта кода для получения дополнительной информации.

string ModuleName = "TestAssembly.dll";
string TypeName = "TestClass";
string MethodName = "TestMethod";

Assembly myAssembly = Assembly.LoadFrom(ModuleName);

BindingFlags flags = (BindingFlags.NonPublic | BindingFlags.Public | 
  BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);

Module [] myModules = myAssembly.GetModules();
foreach (Module Mo in myModules) 
{
 if (Mo.Name == ModuleName) 
     {
     Type[] myTypes = Mo.GetTypes();
     foreach (Type Ty in myTypes)
         {
        if (Ty.Name == TypeName) 
            {
            MethodInfo[] myMethodInfo = Ty.GetMethods(flags);
            foreach(MethodInfo Mi in myMethodInfo)
                {
                if (Mi.Name == MethodName) 
                    {
                    Object obj = Activator.CreateInstance(Ty);
                    Object response = Mi.Invoke(obj, null);
                    }
                }
            }
        }
    }
}
0
ответ дан 3 December 2019 в 14:26
поделиться

"Самый близкий к Вашему вопросу" решение.

Вы могли сделать делегатов из тех отчетов и назвать их путем поиска соответствующей строки в Хеш-таблице:

Public Sub New()
    '...
    ReportTable.Add("Security", New ReportDelegate(AddressOf ShowSecurityReport))
    ReportTable.Add("Config", New ReportDelegate(AddressOf ShowConfigReport))
    ReportTable.Add("RoleUsers", New ReportDelegate(AddressOf ShowRoleUsersReport))
    '...
End Sub

Private Sub ShowSecurityReport()
    '...
End Sub

Private Sub ShowConfigReport()
    '...
End Sub

Private Sub ShowRoleUsersReport()
    '...
End Sub

Private Delegate Sub ReportDelegate()

Private ReportTable As New Dictionary(Of String, ReportDelegate)

Private Sub ShowReport(ByVal reportName As String)
    Dim ReportToRun As ReportDelegate
    If ReportTable.TryGetValue(reportName, ReportToRun) Then
        ReportToRun()
    Else
        pnlMessage.Visible = True
        litMessage.Text = "The report name """ + reportName + """ is invalid."
    End If
End Sub

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

0
ответ дан 3 December 2019 в 14:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: