我对c#和Unity3D有一个问题。我想从单个目录中读取一系列一些到许多JSON文件,并将每个文件的数据反序列化为一个特定的类。我想知道是否有一种快速的方法来循环这个过程,所以我不需要一个大的if/switch
块或任何东西。反序列化很好,但是我在实际上将每个文件的数据分配给包含正确Type
对象的列表时遇到了麻烦。
注意:类名与文件名相同。例如,如果文件名是Cars。json,我想找到一个名为CarManager
的Component
,并使用它在CarManager.cars
的List<Car>
中存储反序列化数据。
我没有经验,我真的不知道如何使用Type
参考。如果有人能解释我如何编写ProcessFile()
方法来成功区分Object
类型,这样我就可以在Unity中存储每个文件的数据,我真的很感激。
欢呼。
namespace Flight {
public class DatasetManager : MonoBehaviour {
private JsonSerializer serialiser;
private StreamReader streamReader;
private string path;
private string fileName;
private string extension;
public void Start() {
// Define Path
path = Application.dataPath + "/Data/";
extension = "json";
// Construct Serialiser
serialiser = new JsonSerializer();
serialiser.Converters.Add(new StringEnumConverter());
serialiser.NullValueHandling = NullValueHandling.Ignore;
// Import Data
Import();
}
private void Import() {
string[] files = Directory.GetFiles(path, "*." + extension);
if(files.Length == 0) return;
for(int i = 0; i < files.Length; i++) ProcessFile(files[i]);
}
private void ProcessFile(string xFile) {
streamReader = File.OpenText(xFile);
// Read Filename
string plural = Path.GetFileNameWithoutExtension(xFile);
string entity = plural.EndsWith("ies") ? plural.Substring(0,plural.Length-3) + "y" : plural.Substring(0,plural.Length-1);
string manager = entity + "Manager";
// Determine Entity & Manager Types
System.Type entityType = System.Type.GetType("Flight." + entity);
System.Type managerType = System.Type.GetType("Flight." + manager);
if(entityType == null || managerType == null) return;
// Determine List Type
System.Type listType = null;
listType = typeof(List<>).MakeGenericType(entityType);
if(listType == null) return;
// Acquire Data
List<dynamic> data = System.Activator.CreateInstance(listType) as List<dynamic>;
data = serialiser.Deserialize(streamReader, typeof(List<dynamic>)) as List<dynamic>;
if(data == null) return;
// Store Data in Game
GameObject theGame = GameObject.FindGameObjectWithTag("Game");
Component theComponent = theGame.GetComponent(manager);
FieldInfo field = managerType.GetField(plural.ToLower());
/*** How can I proceed from here? ***/
List<dynamic> theList = field.GetValue(theComponent) as List<dynamic>;
field.SetValue(theComponent, data);
}
}
}
上面的代码生成一个ArgumentException
:
System.Collections.Generic.List1[系统。Object]不能转换为目标类型:System.Collections.Generic.List1[Flight.Car]
不用担心,已经修复了。以下修改后的ProcessFile()
代码似乎可以正常工作:
private void ProcessFile(string xFile) {
// ...
// ...
// Determine List Type
System.Type listType = typeof(List<>).MakeGenericType(entityType);
if(listType == null) return;
// Acquire Data
streamReader = File.OpenText(xFile);
object data = null;
data = System.Activator.CreateInstance(listType);
data = serialiser.Deserialize(streamReader, listType);
if(data == null) return;
// Store Data in Game
GameObject theGame = GameObject.FindGameObjectWithTag("Game");
Component theComponent = theGame.GetComponent(manager);
FieldInfo field = managerType.GetField(plural.ToLower());
field.SetValue(theComponent, data);
}