2013-08-12 2 views
1

что-то вроде этого возможно - и если да, то как?Parameter.GetType() - Должен ли быть известен тип во время компиляции?

Я хочу создать класс, способный десериализовать данный XML-файл. XML-файл содержит сериализованные значения пользовательского типа, который неизвестен во время компиляции. Я подумал, что можно просто инициализировать класс с помощью параметра SampleObject и затем получить этот тип SampleObject для дальнейшего дальнейшего развития. Но похоже, что тип для всех операций должен быть известен во время компиляции? Есть ли способ обойти это или вы можете объяснить мне эту проблему?

кода приведенный выше пример только для иллюстрации моей дачи

Спасибо за помощь, Янис

Edit: Ваши ответы могут Allready бы решить эту проблему, я буду читать больше на темы «отражение» и «generics», и держите вас в курсе, если я сделаю какой-то прогресс. Так что спасибо за помощь.

Для тех, кто по-прежнему интересуется: Меня попросили задать вопрос и попытаться объяснить его как можно лучше.

Public Function ReadAllObjects() As List(Of myObjectType) 
     Dim result As New List(Of myObjectType) 
     Dim ObjectSerializer As New System.Xml.Serialization.XmlSerializer(result.GetType) 
     Dim FileReader As New System.IO.FileStream(My.Settings.XMLPath, System.IO.FileMode.Open) 
     result = TryCast(ObjectSerializer.Deserialize(FileReader), List(Of myObjectType)) 
     FileReader.Close() 
     RaiseEvent ReadingFinished() 
     Return result 
    End Function 

Это в значительной степени подводит итог того, что я хочу создать: A EasyXmlHandling.dll для дальнейшего использования, который будет инициализирован с используемым в настоящее время типа переменной. Затем предполагается, что он сможет писать и читать из/в XML-файл очень простым способом, просто называя «ReadAllObjects» (возвращает список myObjectType) или «AddObject (ByVal theNewObject)» ... (больше функций)

У меня есть все, что нужно для работы с пользовательским классом типа, поэтому теперь я могу легко повторно использовать код EasyXmlHandling, просто заменив этот тип в исходном коде любым новым классом, который я хочу использовать. Я бы предпочел просто вызвать DLL с образцом объекта (или его тип) и заставить его делать все остальное автоматически.

Я надеюсь, что понятно, но ни мой английский, ни мой технический словарь действительно хорошо;)

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

+1

Вам нужно будет использовать дженерики ... что-то вроде этого 'Public Sub CreateGenericList (Of T) (ByVal SampleObject As T) Dim genericList As New List (Of T) End Sub' - синтаксис может быть немного выключен, но, надеюсь, это укажет вам в правильном направлении. – Tim

+3

Не могли бы вы подробнее рассказать о своей конкретной проблеме? Зачем вам нужен общий список в вашем примере кода, а не только «List (Of Object)»? Вам нужно вызвать определенный общий метод? – sloth

+1

Я только что отредактировал оригинальное сообщение, чтобы уточнить мою актуальную проблему. Думаю, с намеком на «дженерики» и «отражение» я смогу заставить его работать и, надеюсь, не потребует дальнейшей помощи. Но не стесняйтесь читать и отвечать на него :) Еще раз спасибо! – Janis

ответ

1

Нет, это невозможно (по крайней мере, не используя отражение). Весь смысл указания типа в общем списке или любом другом родовом типе заключается в том, что компилятор может выполнять проверку типа компиляции. Если вы не укажете тип во время компиляции, нет никакой пользы для него. Помимо того, что нет никакой выгоды, это также просто не поддерживается. Если вы не знаете типа во время компиляции, вы должны просто использовать Object вместо этого, так как это будет работать с объектами любого типа, например:

Dim myList As New List(Of Object)() 

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

Update

Теперь, когда вы объяснили причину для этого, стало ясно, что генерики ваше решение. Например, вы могли бы реализовать его в качестве общей функции, например:

Public Function ReadAllObjects(Of T)() As List(Of T) 
    Dim result As New List(Of T) 
    Dim ObjectSerializer As New System.Xml.Serialization.XmlSerializer(result.GetType) 
    Dim FileReader As New System.IO.FileStream(My.Settings.XMLPath, System.IO.FileMode.Open) 
    result = TryCast(ObjectSerializer.Deserialize(FileReader), List(Of T)) 
    FileReader.Close() 
    RaiseEvent ReadingFinished() 
    Return result 
End Function 

Тогда вы могли бы назвать это, как это, передавая его, когда-либо тип, который вы хотите:

Dim cars As New List(Of Car) = ReadAllObjects(Of Car)() 
Dim boats As New List(Of Boat) = ReadAllObjects(Of Boat)() 

Как вы можете см., то есть вся цель дженериков. Это очень мощный инструмент, когда вы хотите сохранить свой тип кода, но все же сможете повторно использовать его с разными типами. Отражение, с другой стороны, не очень хорошо подходит в этой конкретной ситуации. Отражение также очень полезно, но его всегда следует рассматривать как вариант последней инстанции. Если есть другой способ сделать это, без отражения, это обычно лучший способ.

+0

Вы можете легко создавать типы 'List (Of T)' во время выполнения с использованием отражения. Однако в этом конкретном случае я хотел бы рассмотреть возможность создания самого метода. – MarcinJuraszek

+0

* Нет, это невозможно *: Ну, вы * можете * создать «правильный» список (Of T) 'используя отражение ... – sloth

+0

@ DominicKexel Хорошая точка. Да, это можно сделать так, но тогда вам нужно будет ссылаться на объект списка как «IList» или «Object», что приведет к поражению большей части точки. Я согласен с вашим оригинальным комментарием - Янис должен объяснить причину *, почему это необходимо. Скорее всего, это ошибочно, но есть небольшая вероятность, что для этого есть веская причина :) –