Issues with Reflection/MonoField Object

I’m trying to use Reflection to instantiate Objects.

The issue I’m running into is that all public fields are returned as type MonoField and not as their actual String or int types. It seems to be causing System.Reflection.FieldInfo.SetValue to not be casting my object correctly. I’m unsure what a Monofield is, it’s not in the MSDN, and I’m assuming it has to do with Mono as a .NET framework. I can’t find any information on it or what it is for/can do with it.

It seems to be blocking the use of Reflection, and I’m curious if there are any workaround for it.

1 Like

do you have unity C# code showing your problem?

I actually just fixed the issue.

Turns out System.Reflection.FieldInfo.GetType() returns MonoField, but System.Reflection.FieldInfo.TypeInfo returns the appropriate type.

It provides an alternative to the System.Xml serialization, as I heard including it can impact final build size a fair amount.

It takes a Hierarchy XML structure and converts it into a flattened struct that is much easier to read.

	private PrefabInfo ConvertToStruct(Node prefabNode)
	{
		PrefabInfo prefab = new PrefabInfo();
		
		Type PrefabInfoType = typeof(PrefabInfo);
		FieldInfo[] fieldInfo = PrefabInfoType.GetFields();
		
		foreach (FieldInfo info in fieldInfo)
		{
			Node node = prefabNode.GetNode(info.Name);
			if(node != null)
			{
				switch(info.FieldType.ToString())
				{
					case "System.String":
						info.SetValue(prefab, node.value);
						break;
					case "System.Boolean":
						if(node.value[0] == 't' || node.value[0] == 'T')
						{	
							info.SetValue(prefab, true);
						}
						else
						{
							info.SetValue(prefab, false);
						}
						break;
					case "UnityEngine.Vector2":
						Vector2 vec = new Vector2();
						vec.x = Convert.ToSingle(node.GetNode("x").value);
						vec.y = Convert.ToSingle(node.GetNode("y").value);
						info.SetValue(prefab, vec);
						break;
					case "System.Int32":
						info.SetValue(prefab, Convert.ToInt32(node.value));
						break;
					default:
						Debug.Log("Default Case");
						break;
				}
				Debug.Log(info.Name + " = " + info.GetValue(prefab));
			}
		}
		return prefab;
	}

This is now functioning though, so long as I don’t use GetType and instead rely on the FieldType property.

3 Likes

I’m a .NET developer about to start investigating Unity to see if we can use it. So I stumbled upon this to see if it supports reflection (I guess it does, thanks Ntero!).

I see this same issue often from people developing .NET applications when diving into reflection. Every object has a “GetType” method which returns the type of that object. So the FieldInfo object was returning its type “MonoField” when you called GetType. However, that MonoField object has the property “TypeInfo” which you found which is what is supposed to be used to inform you of that reflected field’s type. So just be aware of its use (GetType is infinitely useful) and what it means especially when using reflection. Good luck in your development!