Можно ли определить тип класса при создании экземпляра или преобразовать тип впоследствии без преобразования? - PullRequest
0 голосов
/ 21 июня 2020

Например: у меня есть несколько классов, которые наследуются от одного и того же класса.

Public Class MasterClass
    ' content
End Class

Public Class ClassA
  Inherits MasterClass
    'content
End Class
Public Class ClassB
  Inherits MasterClass
    'content
End Class
Public Class ClassC
  Inherits MasterClass
    'content
End Class

И я хочу решить, какой из них мне нужен во время выполнения. Тогда я могу сделать что-то вроде этого:

Private myInstance As MasterClass
If conditionA Then
    myInstance = New ClassA
ElseIf conditionB Then
    myInstance = New ClassB
Else
    myInstance = New ClassC
End

Но это может занять довольно много времени, и мне все равно придется приводить его каждый раз, когда я его использую.

Я могу присвоить тип переменной , но я не знаю, как использовать этот тип для создания нового экземпляра этого типа ..

Dim storedType As Type = GetType(ClassA)
Dim someInstance = New storedType 'Does not work

Есть ли способ лучше? Можете ли вы изменить тип переменной во время выполнения?

Ответы [ 2 ]

1 голос
/ 21 июня 2020

В этом случае Интерфейсы - лучший выбор

Interface ABC
    Property Text As String
    Property Value As Integer
End Interface
Public Class MasterClass

End Class

Public Class ClassA
    Inherits MasterClass : Implements ABC
    Property Mystr As String Implements ABC.Text
    Property Sum As Integer Implements ABC.Value
End Class
Public Class ClassB
    Inherits MasterClass : Implements ABC
    Property MyText As String Implements ABC.Text
    Property Value As Integer Implements ABC.Value
End Class
Public Class ClassC
    Inherits MasterClass : Implements ABC
    Property str As String Implements ABC.Text
    Property Value As Integer Implements ABC.Value
End Class

использование

Dim myABC As ABC
If conditionA Then
    myABC = New ClassA
ElseIf conditionB Then
    myABC = New ClassB
Else
    myABC = New ClassC
End If
myABC.Text = "Interface"
1 голос
/ 21 июня 2020

Мне все равно нужно использовать его каждый раз, когда я его использую.

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

Можете ли вы изменить тип переменной во время выполнения?

Конечно, но вы должны использовать ее так, как она появляется. Длинные цепочки «если мой объект является экземпляром x, тогда приведите мой объект как x и используйте метод X1, иначе, если мой объект является y, затем приведите его как y и вызовите y1», не являются полиморфными / не используют принципы наследования должным образом - вы должен вызывать myobject.whatever, и если мой объект является x, то происходит x1, и если это да, то происходит y1

Я хочу решить, во время выполнения какой из них мне нужен

Но вам не нужно делать это в классе, который знает о классе a / b / c - каждый из класса a / b / c может это делать и, следовательно, становится самодостаточным. Вы можете поместить все свои экземпляры в массив родительского типа и посетить каждый, спрашивая их, обрабатывают ли они условие, и использовать тот, который говорит, что может

Рассмотрим немного лучший пример из реального мира, чем этот искусственный класс a / b / c троп:

Вам поручено написать приложение, которое может загружать изображение (png, jpg или gif) откуда-нибудь (http, ftp или расположение на диске), вращать его и загружать в другое место

Вы решили создать родительский элемент ImageRotator, который определяет функцию CanHandle и функцию поворота. У него есть 3 подкласса: один обрабатывает jpg, второй вращает gif, а второй - png. При представлении имени файла в формате PNG JpgRotator отвечает «Нет», когда его спрашивают, может ли он с ним справиться и т.д. Опять же, родитель их вообще не реализует. Эти три подкласса реализуют возможность вверх / вниз по http, ftp и местоположению на диске.

Вы создаете экземпляр каждого ротатора и помещаете его в массив типа ImageRotator. Вы также создаете экземпляр каждого движка в массиве, который является родительским типом FileMover.

Ваш пользователь указывает jpg в URL-адресе http и сохраняет его в конце на диске. Вы l oop ваши FileMovers и спрашиваете каждого, поддерживают ли они местоположение, указанное пользователем. HTTP-движок говорит, что вы вызываете его загрузку по временному пути. Затем вы проходите путь к каждому ротатору, ротатор jpg говорит да, вы вызываете вращение. Наконец, вы ищете другой движок, который может обрабатывать выходной путь локального диска ...

Кто-то решает расширить вашу программу с помощью подключаемого модуля dll, который добавляет ему возможность помещать файлы в базу данных и из нее. и поддерживают изображения tiff ... игнорируя магию c того, как экземпляры их классов попадают в ваши массивы, вы можете видеть, что ваша программа теперь может перемещать эти новые местоположения и типы, потому что logi c для того, обрабатывают ли они db / tiff не является частью вашего кода .. ваш код просто обрабатывает все последовательно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...