前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C#脚本实践(四): 反射与序列化

C#脚本实践(四): 反射与序列化

作者头像
逍遥剑客
发布2018-05-23 16:26:18
1K0
发布2018-05-23 16:26:18
举报
  • 序列化 - 这个比较简单, .net直接就支持, 以XML序列化为例: public static string SerializeToString (object obj)  
  • {  
  •     XmlSerializer serializer = new XmlSerializer (obj.GetType ());  
  • using (StringWriter writer = new StringWriter()) {  
  •         serializer.Serialize (writer, obj);  
  • return writer.ToString ();  
  •     }  
  • }  
  • public static T SerializeFromString<T> (string xml)  
  • {  
  •     XmlSerializer serializer = new XmlSerializer (typeof(T));  
  • using (StringReader reader = new StringReader(xml)) {  
  • return (T)serializer.Deserialize (reader);  
  •     }  
  • }  

  1. public struct Vector3  
  2. {  
  3. public float x;  
  4. public float y;  
  5. public float z;  
  6. }  
  7. public class TestClass  
  8. {  
  9. public int testInt = 1234;  
  10. public float testFloat = 0.2341f;  
  11. public bool[] boolArray = {truefalsefalsetrue};  
  12. public Vector3 position;  
  13. public TestClass ()  
  14.     {  
  15. this.position.x = 100;  
  16. this.position.y = 100;  
  17. this.position.z = 0;  
  18.     }  
  19. }  

结果如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <TestClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  3. <testInt>1234</testInt>
  4. <testFloat>0.2341</testFloat>
  5. <boolArray>
  6. <boolean>true</boolean>
  7. <boolean>false</boolean>
  8. <boolean>false</boolean>
  9. <boolean>true</boolean>
  10. </boolArray>
  11. <position>
  12. <x>100</x>
  13. <y>100</y>
  14. <z>0</z>
  15. </position>
  16. </TestClass>

到时候把string用mono api传到C++里, 爱怎么存怎么存. 二进制格式同理

  • 反射
    • .net本身也支持反射, 问题是如何反射到C++里
    • 用mono api取得类的meta信息, 然后反应到编辑器上去编辑
    • 如果想偷懒的话, 可以直接用mono创建个窗口, 放个propertygrid控件, 再这个窗口嵌入到主编辑器的界面
int depth = 0;  
void ListFields(MonoObject* object)  
{  
    assert(NULL != object);  
    ++depth;  
    MonoClass* objectClass = mono_object_get_class(object);  
 const char* className = mono_class_get_name(objectClass);  
    printf("[%s]\n", className);  
 void* iter = NULL;  
    MonoClassField* field = NULL;  
 while (field = mono_class_get_fields(objectClass, &iter))  
    {  
 for (int i = 0; i < depth; ++i)  
        {  
            printf("\t");  
        }  
 const char* fieldName = mono_field_get_name(field);  
        printf("%s : ", fieldName);  
        MonoType* fieldType = mono_field_get_type(field);  
 int type = mono_type_get_type(fieldType);  
 switch (type)  
        {  
 case MONO_TYPE_BOOLEAN:  
            {  
 bool boolValue = false;  
                mono_field_get_value(object, field, &boolValue);  
                printf("%s\n", boolValue ? "true" : "false");  
            }  
 break;  
 case MONO_TYPE_I4:  
            {  
 int intValue = 0;  
                mono_field_get_value(object, field, &intValue);  
                printf("%d\n", intValue);  
            }  
 break;  
 case MONO_TYPE_R4:  
            {  
 float floatValue = 0;  
                mono_field_get_value(object, field, &floatValue);  
                printf("%f\n", floatValue);  
            }  
 break;  
 case MONO_TYPE_CHAR:  
 case MONO_TYPE_I1:  
 case MONO_TYPE_U1:  
 case MONO_TYPE_I2:  
 case MONO_TYPE_U2:  
 case MONO_TYPE_U4:  
 case MONO_TYPE_I:  
 case MONO_TYPE_U:  
 case MONO_TYPE_I8:  
 case MONO_TYPE_U8:  
 case MONO_TYPE_R8:  
            {  
 //@todo 
            }  
 break;  
 case MONO_TYPE_SZARRAY:  
            {  
                MonoObject* value = mono_field_get_value_object(mono_domain_get(), field, object);  
                MonoArray* array = (MonoArray*)value;  
 uintptr_t size = mono_array_length(array);  
                MonoClass* elementClass = mono_class_get_element_class(mono_object_get_class(value));  
                MonoType* elementType = mono_class_get_type(elementClass);  
 switch (mono_type_get_type(elementType))  
                {  
 case MONO_TYPE_BOOLEAN:  
                    {  
 bool* data = mono_array_addr(array, bool, 0);  
 for (int i = 0; i < size; ++i)  
                        {  
                            printf("%s ", data[i] ? "true" : "false");  
                        }  
                        printf("\n");  
                    }  
 break;  
 default: //@todo 
 break;  
                }  
                className = mono_class_get_name(elementClass);  
            }  
 break;  
 case MONO_TYPE_STRING:  
            {  
                MonoObject* value = mono_field_get_value_object(mono_domain_get(), field, object);  
                MonoString* valueString = (MonoString*)value;  
 const char* valueCStr = mono_string_to_utf8(valueString);  
                printf("%s\n", valueCStr);  
            }  
 break;  
 default:  
            {  
                MonoObject* value = mono_field_get_value_object(mono_domain_get(), field, object);  
                ListFields(value);  
            }  
 break;  
        }  
    }  
    --depth;  
} 

输出:

  1. TestClass  
  2.         testBool : false  
  3.         testInt : 1234  
  4.         testFloat : 0.234100  
  5.         testString : hello  
  6.         boolArray : true false false true  
  7.         position : Vector3  
  8.                 x : 100.000000  
  9.                 y : 100.000000  
  10.                 z : 0.000000  

C#脚本实践(三): 集成到游戏

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2011年11月26日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档