【发布时间】:2017-08-17 10:47:12
【问题描述】:
我目前正在处理一个包含数据的文件。
数据可以在不同的类中,并且这些类在同一个文件中定义。
我目前能够将类输出到 json,并且我能够将数据作为 json 转换为这些类
问题是我希望能够动态创建一个类来处理移动中的数据,而不是简单地将其打印为文件。
类示例:
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
类型是从带有枚举的 Uint 定义的:
Public Enum GameDataTypeEnum
Int = -1
Bool = -2
[String] = -3
[Double] = -4
I18N = -5
UInt = -6
Vector = -99
End Enum
为了解决这个问题,我尝试将枚举类型转换为 vb.net 类型,例如:
Dim myType1 As Type = Type.GetType("System.Int32")
然后我尝试像这样使用 Activator.CreateInstance:
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"))
这很好用,但是回顾这个解决方案它是不可行的,因为类有不同的类型。无论如何,您会看到从文件中创建类并动态生成它们吗?
最坏的情况是我可以手动生成所有类,但是有很多类并且需要很多时间
Vincent 的解决方案可以很好地解决一个小问题。
当我读取文件时,一个字段可能包含另一个字段,这些字段称为向量,可以表示为:List Of (Contained Value)
现在我只需这样做:
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
我的testcast() 函数只是返回一个字符串,将枚举转换为正确的格式,例如Int 到System.Int32
对于我的 getFieldTypeString 我有:
If isPrimitiveFieldType(field) Then
Return getPrimitiveFieldTypeString(field)
Else
Return getCompositeFieldTypeString(field)
End If
原始给出:
Private Function getPrimitiveFieldTypeString(field As GameDataField) As String
Return If(field.fieldType > 0, classDefinitions(CInt(field.fieldType)).Name, field.fieldType.ToString())
End Function
复合给出:
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
如何向 ClassProperties 添加一个属性来表示:
List of a List of a Type
【问题讨论】:
-
@VisualVincent 回想一下我不认为字典方法是个好主意,因为在类中有不同的类型。所以就像在示例类中一样,我无法放置所有数据。是否有可能有类似的方法,但使用类?
-
这看起来很有希望:stackoverflow.com/a/26971289/3740093
-
此外,如果您使用该代码,请在此答案中进行建议的更改:stackoverflow.com/a/27499618/3740093
-
如果你想 set 属性,那么我的
GetProperty方法将不起作用。一会儿我会写一个更完整的答案。 -- 另外,请记住,Dim obj(1) As Object创建了一个由 两个 元素组成的数组,因为您声明了它的 上界索引我>。要使用一项声明它,请执行Dim obj(0) ...或我喜欢的方式:Dim obj(1 - 1) ...。