Как я могу присвоить значение ряду различных переменных в коллекции, используя циклы? - PullRequest
0 голосов
/ 03 января 2019

У меня есть проблема, которая беспокоила меня некоторое время.Рассмотрим следующий код:

    Public Class Class1

        Dim VariableList as New List(of Object) From {MainForm.X, MainForm.Y,
     SettingsForm.Z, SettingsForm.Textbox1.Text} '...etc.

    Sub SetToZero()
        For Each Element in VariableList
            Element = 0
        Next
    End Sub

    Sub SetToCustomValue(value As Double)
        For Each Element in VariableList
            Element = value
        Next
    End Sub

    Sub LoadValuesFromFile()
        Dim path As String = MainForm.GetPath()

        For Each Element in VariableList
            Element = File.Readline()
        Next
    End Sub

    Sub SaveValuesToFile()
        Dim path As String = MainForm.GetPath()

        For Each Element in VariableList
            Element = File.Writeline()
        Next
    End Sub


    'and more similar functions/subs

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

Чтение значений не является проблемой.Их написание заключается в том, что, когда я объявляю VariableList в верхней части моего класса, этот List просто делает копию каждой переменной, а не поддерживает ссылку на нее.Это означает, что если, скажем, одна из функций изменяет MainForm.X в этом списке, фактическая переменная MainForm.X не изменяется.Чтобы работать со ссылками, мне пришлось бы отказаться от циклов и назначать каждую переменную вручную в каждой функции.Который, очевидно, много плохого кода.Я хочу объявить этот список переменных только один раз, а затем использовать циклы, как в этом примере кода, который я написал выше.У меня вопрос: как я могу создать такой контейнер (List, Array и т. Д.), Который бы сохранял ссылки на исходные переменные в нем и делал возможным приведенный выше код?

1 Ответ

0 голосов
/ 04 января 2019

Нет простого способа хранить указатели на переменные в VB.NET.В качестве обходного пути вы можете использовать класс для хранения ваших переменных, так как класс всегда используется в качестве указателя.

Вот пример способа достижения этого с помощью ContainerClass, которому принадлежит словарь целых чисел,Один интерес этого метода заключается в том, что вы можете динамически объявлять и называть «переменные».На самом деле они будут управляться KeyValuePair.После того, как вы создали экземпляр этого класса, вы можете использовать его для «управления» вашими переменными, используя этот класс в качестве указателя.

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

Public Class Form2
    'This is the container class which will be used to bypass the lack of pointers
    'if you wanted to change a property, like the window width, it would be more difficult, but simples variables will be no trouble
    Private variableContainer As New VariableContainer

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        variableContainer.AddVar("X", 5)
        variableContainer.AddVar("Y", 15)

        Debug.Print(variableContainer.GetVar("X"))
        Debug.Print(variableContainer.GetVar("Y"))

        variableContainer.SetAllVar(42)
        Debug.Print("Next line will print 42")
        Debug.Print(variableContainer.GetVar("X"))
    End Sub
End Class

Public Class VariableContainer
    'I know a public variable wouldn't need the fancy functions down there, but it's usually better to encapsulate, especially if you're working with a team
    'and "future you" count as a teammate, never forget that...
    Private list As New Dictionary(Of String, Integer)

    Public Sub AddVar(ByVal name As String, ByVal value As Integer)
        list.Add(name, value)
    End Sub

    Public Function GetVar(ByVal name As String) As Integer
        If list.ContainsKey(name) Then
            Return list(name)
        Else
            'I choose -1 arbitrarily, don't put too much thinking into this detail
            Return -1
        End If
    End Function

    Public Sub SetVar(ByVal name As String, ByVal num As Integer)
        If list.ContainsKey(name) Then
            list(name) = num
        End If
    End Sub

    Public Sub SetAllVar(ByVal num As Integer)
        Dim dict As New Dictionary(Of String, Integer)

        For Each item As KeyValuePair(Of String, Integer) In list
            dict.Add(item.Key, num)
        Next

        list = dict
    End Sub
End Class

Веселитесь!

...