Где у меня есть несколько параметров для функции, как передать один список, содержащий все аргументы в точном порядке в VB. NET? - PullRequest
1 голос
/ 09 марта 2020

У меня есть функция, которая содержит несколько параметров, как обычно, например:

Function MyFunction(ByRef Param1 As String, ByRef Param2 As String, ByRef Param3 As String)
    ' some code
End Function

Я хочу иметь возможность передать список, содержащий все рассматриваемые параметры, функции.

Dim MyList As New List(Of String) From {"I am a string", "I am also a string", "Again, a string"}

Существует ли какая-либо встроенная подпрограмма или какой-либо другой метод, который я мог бы сделать сам, который позволил бы мне, предполагая, что эти аргументы находятся в том же порядке, что и параметры для MyFunction, передать этот список как оно стоит в MyFunction?

Ответы [ 3 ]

1 голос
/ 10 марта 2020

Создайте класс, который представляет данные, которые вы хотите передать:

Class X
  Public Property Param1 as String
  Public Property Param2 as String
  Public Property Param3 as String
End Class

Создайте перегрузку вашей функции, которая принимает этот аргумент:

Function MyFunction(p as X)
    Console.WriteLine("P1 is " + x.Param1)
    Console.WriteLine("P2 is " + x.Param2)
    Console.WriteLine("P3 is " + x.Param3)
    Return ...
End Function

Вы можете иметь 3 Если вам нужна версия параметра, просто вызовите перегрузку:

Это можно вызвать либо с разделенными значениями, либо с коллекцией:

MyFunction("This", "for", "example")

Dim s() as String = {"This", "for", "example"}
MyFunction(s)
1 голос
/ 10 марта 2020

Вы можете использовать Reflection, чтобы приблизиться к желаемому результату. Если вы используете модуль для определения этой вспомогательной функции,

Public Module MyModule

    Function callByName(Of T)(name As String, args As IEnumerable(Of T)) As T
        Dim type = GetType(MyModule)
        Dim mi = type.GetMethod(name)
        Return CType(mi.Invoke(Nothing, args.Select(Function(o) DirectCast(o, Object)).ToArray()), T)
    End Function

    Function callByName(Of T)(instance As Object, name As String, args As IEnumerable(Of T)) As T
        Dim type = instance.GetType()
        Dim mi = type.GetMethod(name)
        Return CType(mi.Invoke(instance, args.Select(Function(o) DirectCast(o, Object)).ToArray()), T)
    End Function

End Module

Теперь здесь есть некоторые неизвестные. Я не знаю, как объявлена ​​ваша функция MyFunction. Каков его тип возврата? Это экземпляр экземпляра какого-то класса или это модуль? Предполагая, что он находится в том же модуле, который я поставил выше, MyModule, поместите его туда.

Public Function MyFunction(ByRef Param1 As String, ByRef Param2 As String, ByRef Param3 As String) As String
    Return Param1 & Param2 & Param3 & "Static"
End Function

Он также может быть членом экземпляра вызывающего класса. Поэтому поместите это туда

Public Function MyFunction(ByRef Param1 As String, ByRef Param2 As String, ByRef Param3 As String) As String
    Return Param1 & Param2 & Param3 & "Instance"
End Function

(верно, они идентичны, за исключением того, что они возвращают)

Так что назвать их легко. Это просто так

Dim args = {"a", "b", "c"}
Dim resultStatic = callByName("MyFunction", args)
Dim resultInstance = callByName(Me, "MyFunction", args)

resultStati c = "abcStati c"
resultInstance = "abcInstance"

Видите? Вы передаете имя функции в виде строки и аргументы. Это будет работать только тогда, когда все аргументы имеют одинаковый тип, а возвращаемый тип функции одинаков. Вы также можете изменить дженерики вокруг. Но, опять же, я не знаю тип возвращаемого значения вашей функции.

Вы также можете заставить ее работать, я полагаю, Sub. Просто поиграйте с вещами Reflection в callByName.

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

Если вам не нравится использовать строку для вызова метода, вы также можете используйте NameOf

Dim resultStatic = callByName(NameOf(MyModule.MyFunction), args)

Этот ответ потребует нулевой перезаписи существующих функций. Я полагаю, это то, что вы ищете.

0 голосов
/ 10 марта 2020

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

Dim MyList As New List(Of String) From {"I am a string", "I am also a string", "Again, a string"}

Private Overloads Function MyFunction(ByRef Param1 As String, ByRef Param2 As String, ByRef Param3 As String) As String
    Return Param1 & Param2 & Param3
End Function

Private Overloads Function MyFunction(lst As List(Of String)) As String
    Dim Param1 = lst(0)
    Dim Param2 = lst(1)
    Dim Param3 = lst(3)
    Return Param1 & Param2 & Param3
End Function

Private Sub CallFunctions()
    MyFunction(MyList(0), MyList(1), MyList(2))
    'Or
    MyFunction(MyList)
End Sub
...