我将 Unity 与 GameSparks 一起使用,并且有一个序列化程序脚本,它将 GameSparks 数据对象转换为 ac# 模型。脚本如下所示:
public static object GSDataToObject(GSData gsData)
{
//Debug.Log("GSSerializer Return: \n"+gsData.JSON);
Type objType = Type.GetType(gsData.GetString("type"));
object obj = Activator.CreateInstance(objType);
foreach(var typeField in objType.GetFields())
{
if(!typeField.IsNotSerialized)
{
if(typeField.FieldType == typeof(string))
{
typeField.SetValue(obj, gsData.GetString(typeField.Name));
}
else if(typeField.FieldType == typeof(int))
{
typeField.SetValue(obj, (int)gsData.GetNumber(typeField.Name).Value);
}
else if(typeField.FieldType == typeof(float))
{
typeField.SetValue(obj, (float)gsData.GetFloat(typeField.Name).Value);
}
else if(typeField.FieldType == typeof(bool))
{
typeField.SetValue(obj, gsData.GetBoolean(typeField.Name));
}
else if(typeField.FieldType == typeof(DateTime))
{
typeField.SetValue(obj, gsData.GetDate(typeField.Name));
}
else if((typeField.FieldType == typeof(List<string>) || typeField.FieldType == typeof(string[]) ))
{
typeField.SetValue(obj, (typeField.FieldType == typeof(List<string>)) ? (object)gsData.GetStringList(typeField.Name) : gsData.GetStringList(typeField.Name).ToArray());
}
else if((typeField.FieldType == typeof(List<int>) || typeField.FieldType == typeof(int[])) )
{
typeField.SetValue(obj, (typeField.FieldType == typeof(List<int>)) ? (object)gsData.GetIntList(typeField.Name) : gsData.GetIntList(typeField.Name).ToArray());
}
else if((typeField.FieldType == typeof(List<float>) || typeField.FieldType == typeof(float[])) )
{
typeField.SetValue(obj, (typeField.FieldType == typeof(List<float>)) ? (object)gsData.GetFloatList(typeField.Name) : gsData.GetFloatList(typeField.Name).ToArray());
}
else if(typeField.FieldType.IsClass && !typeField.FieldType.IsGenericType && !typeField.FieldType.IsArray)
{
typeField.SetValue(obj, GSDataToObject(gsData.GetGSData(typeField.Name)));
}
else if(!typeField.FieldType.IsArray && typeof(IList).IsAssignableFrom(typeField.FieldType))
{
IList genericList = Activator.CreateInstance(typeField.FieldType) as IList;
foreach(GSData gsDataElem in gsData.GetGSDataList(typeField.Name))
{
object elem = GSDataToObject(gsDataElem);
genericList.Add(elem);
}
typeField.SetValue(obj, genericList);
}
else if(typeField.FieldType.IsArray)
{
List<GSData> gsArrayData = gsData.GetGSDataList(typeField.Name);
// create a new instance of the array. The Activator class cannot do this for arrays //
// so this will create a new array of types inside the array, with the count of what is in the gsdata list //
Array newArray = Array.CreateInstance(typeField.FieldType.GetElementType(), gsArrayData.Count);
object[] objArray = new object[gsArrayData.Count]; // create a new array of objects where the serialized objects will be kept
for(int i = 0; i < gsArrayData.Count; i++)
{
objArray[i] = GSDataToObject(gsArrayData[i]); // convert the JSON data inside the list to an object
}
Array.Copy(objArray, newArray, objArray.Length); //covert the object[] to the original type
typeField.SetValue(obj, newArray);
}
}
}
return obj;
}
我的模型是这样的:
[System.Serializable]
public class UserData
{
public string name;
public string email;
}
然后当我从 GameSparks 获取数据时调用脚本,如下所示:
UserData uData = new UserData();
uData = GameSparksSerialiser.GSDataToObject(response.ScriptData.GetGSData("@userReturn")) as UserData;
现在,这一切都很完美,但是如果我决定从现在开始在所有新创建的文档(mongodb)中添加一个新字段,我就有问题了。我在 Unity 中将新字段添加到我的模型中,如下所示:
[System.Serializable]
public class UserData
{
public string name;
public string email;
public bool isAdmin;
}
这对所有新文档都没有错误,但是在尝试序列化旧文档时,我收到此错误:
System.InvalidOperationException: Nullable object must have a value.
现在,我怎样才能避免这种情况,使用序列化程序脚本......是否可以不犯错误,所以我不必更改所有旧文档?
希望提前帮助和感谢:-)