I am currently working with a file that has data inside.
The data can be in various classes and those classes are defined in the same file.
I am currently able to output the classes to json and also I am able to cast the data as json to those classes
The problem is I would like to be able to create a class dynamically to handle the data on the go not simply print it out as file.
Example of class:
Class id:4 - name Item
public Int id
public I18N nameId
public Int typeId
public I18N descriptionId
public Int iconId
public Int level
public Int realWeight
public Bool cursed
public Int useAnimationId
public Bool usable
public Bool targetable
public Bool exchangeable
public Double price
public Bool twoHanded
public Bool etheral
public Int itemSetId
public String criteria
public String criteriaTarget
public Bool hideEffects
public Bool enhanceable
public Bool nonUsableOnAnother
public Int appearanceId
public Bool secretRecipe
public Int recipeSlots
public vector<UInt> recipeIds
public vector<UInt> dropMonsterIds
public Bool bonusIsSecret
public vector<EffectInstance> possibleEffects
public vector<UInt> favoriteSubAreas
public Int favoriteSubAreasBonus
public Int craftXpRatio
public Bool needUseConfirm
public Bool isDestructible
public vector<vector<Double>> nuggetsBySubarea
public vector<UInt> containerIds
public vector<vector<Int>> resourcesBySubarea
The types are defined from a Uint with an enum:
Public Enum GameDataTypeEnum
Int = -1
Bool = -2
[String] = -3
[Double] = -4
I18N = -5
UInt = -6
Vector = -99
End Enum
To solve this I tried to translate the enum type to the vb.net type for instance:
Dim myType1 As Type = Type.GetType("System.Int32")
I then tried using the Activator.CreateInstance like this:
Dim Type1 As Type = Type.GetType("System.String")
Dim Type2 As Type = Type.GetType("System.Int32")
Dim dictType As Type = GetType(Dictionary(Of , )).MakeGenericType(Type1, Type2)
Dim dict = Activator.CreateInstance(dictType)
dict.add("test", 32)
Console.WriteLine(dict.Item("test"))
This works fine however looking back at this solution it is not viable as the classes have different types. Would you see anyways to create the classes from the file and dynamically generate them?
Worst case scenario I could generate all the classes manually but there is a lot of classes and would take a lot of time
Vincent's solution works fine apart for a minor problem.
When I read a file there is the possibility that a field can conatain another field those are called vectors which can be represented by: List Of (Contained Value)
For now I Simply do this:
For Each field As GameDataField In classDefinition.Value.Fields
Console.WriteLine(field.fieldName & " --- " & testcast(getFieldTypeString(field)))
Console.WriteLine(field.fieldName & " --- " & field.fieldType)
ClassProperties.Add(field.fieldName, Type.GetType(testcast(getFieldTypeString(field))))
Next
My testcast()
function simply returns a string converting the enum to correct format like Int
to System.Int32
And for my getFieldTypeString I have:
If isPrimitiveFieldType(field) Then
Return getPrimitiveFieldTypeString(field)
Else
Return getCompositeFieldTypeString(field)
End If
Primitive gives:
Private Function getPrimitiveFieldTypeString(field As GameDataField) As String
Return If(field.fieldType > 0, classDefinitions(CInt(field.fieldType)).Name, field.fieldType.ToString())
End Function
Composite gives:
Private Function getCompositeFieldTypeString(field As GameDataField) As String
Dim compositeFieldTypeBuilder As New StringBuilder()
compositeFieldTypeBuilder.Append("System.Collections.Generic.List(Of ")
If getFieldTypeString(field.innerField) = "UInt" Then
compositeFieldTypeBuilder.Append("UInt32)")
ElseIf getFieldTypeString(field.innerField) = "Int" Then
compositeFieldTypeBuilder.Append("Integer)")
Else
compositeFieldTypeBuilder.Append(getFieldTypeString(field.innerField)).Append(")")
End If
Return compositeFieldTypeBuilder.ToString()
End Function
How could I add a property to the ClassProperties to represent:
List of a List of a Type