相关文章推荐
暴走的荒野  ·  社区精选组件 - Ant Design·  1 年前    · 
腼腆的遥控器  ·  php ...·  1 年前    · 
含蓄的人字拖  ·  AWS ...·  1 年前    · 
逃跑的墨镜  ·  Azure OpenAI Service ...·  2 年前    · 

上一章通过反射实现创建动态编辑栏,但是此时的编辑栏还并没有和结构体数据关联。本章将实现编辑栏中修改的数据将反馈到对应的结构体中,并最后通过序列化将结构体数据以文本的形式进行存储

1、FieldInfo.SetValue方法

将给定对象的字段设置为给定值,查阅了C#的官方文档,上面的案例是这样的

using System;
using System.Reflection;
using System.Globalization;
public class Example
    private string myString;
    public Example()
        myString = "Old value";
    public string StringProperty
            return myString;
public class FieldInfo_SetValue
    public static void Main()
        Example myObject = new Example();
        Type myType = typeof(Example);
        FieldInfo myFieldInfo = myType.GetField("myString", 
            BindingFlags.NonPublic | BindingFlags.Instance); 
        // Display the string before applying SetValue to the field.
        Console.WriteLine( "\nThe field value of myString is \"{0}\".", 
        myFieldInfo.GetValue(myObject)); 
        // Display the SetValue signature used to set the value of a field.
        Console.WriteLine( "Applying SetValue(Object, Object)."); 
        // Change the field value using the SetValue method. 
        myFieldInfo.SetValue(myObject, "New value"); 
        // Display the string after applying SetValue to the field.
        Console.WriteLine( "The field value of mystring is \"{0}\".", 
            myFieldInfo.GetValue(myObject));
/* This code example produces the following output:
The field value of myString is "Old value".
Applying SetValue(Object, Object).
The field value of mystring is "New value".

这段代码在参数是类的对象的时候是毫无问题的,但是传进来结构体变量的时候,就会出现没有附上值的问题。这个主要是跟结构体是值类型,类是引用类型有关。

Fieldinfo.SetValue(object,object),里面的参数都是引用类型的,而结构体是指类型,在调用该方法传结构体变量的时候,会将结构体赋值一份新的,然后在方法里面对新的值进行了修改,而传进去原来的结构体并没有任何改变。所以,在调用SetValue之前,先将结构体进行装箱操作变成Object类型的变量,然后,在进行拆箱操作,将Object变量转换成结构体变量。代码如下:

    public static object SetValue_ReflectMethod<T>(T obj, string paramName, string paramValue)
        //先装箱 变成引用类型的
        object tempObj = obj;
        if (obj != null)
                Type tempType = obj.GetType();
                //设置字段
                FieldInfo tempFI = tempType.GetField(paramName);
                tempFI.SetValue(tempObj, Convert.ChangeType(paramValue, tempFI.FieldType));
                //设置属性
                //PropertyInfo tempPI = tempType.GetProperty(paramName);
                //tempPI.SetValue(tempObj, Convert.ChangeType(paramValue, tempPI.PropertyType), null);
            catch (Exception e)
                Debug.Log("编辑错误" + e.Message);
                tempObj = null;
        return tempObj;

我将这个方法进行了简单的泛型处理,这样保证不管是什么结构体或类都可以作为参数传递进来,并进行转换。方法最后,返回的是一个Object类型的变量,对这个变量进行拆箱操作就可以了:

        object tempObject = SetValue_ReflectMethod(curEditorRP, name, value);
        if (null == tempObject)
            tempEditorSucced = false;
            return tempEditorSucced;
        curEditorRP = (PD_RoutePoint)tempObject;

在每一个编辑栏的输入框组建中都添加了编辑结束响应事件,保证每次对单个编辑框编辑的时候,结构体的数据都会得到修改如图所示:当对单个编辑框进行修改的时候,右侧的Inspector面板上的结构体字段的值也会相应的改变,在输入错误的时候,还加入了相应的处理,出现输入的值和字段类型不匹配则回到上一个输入框的值,并且结构体不发生改变。

最后,将修改后的结构体变量的值存成文本文件:

            string tempJson = JsonUtility.ToJson(curEditorRP);
            string url=M_CurProjectAssetPath+ "/ResourceData/Test.json";
                FileInfo file = new FileInfo(url);
                //判断有没有文件,有则打开文件,,没有创建后打开文件
                StreamWriter sw = file.CreateText();
                sw.WriteLine(tempJson);
                //注意释放资源
                sw.Close();
                sw.Dispose();
            catch (Exception e)
                Debug.Log(e.Message);

1、初步具备了根据结构体字段来动态创建编辑框的功能

2、可以在输入框中对结构体的对应名称字段进行修改,并且编辑框中还加入了错误输入的处理

3、将结构体数据保存成Json文件

4、尚不具备对泛型的处理

未完待续。。。。。

Unity本地化数据处理 unity开发中,我们经常会遇到一些数据需要暂时保存起来,以便下次程序开始时继续使用,这时我们会用到PlayerPrefs数据处理,这里拿我前面开发登录账号的文章举例子说一下,那时开发我们用到的是将用户的信息写入文件中进行保存,需要的时候再读取出来,更改的时候也要读取对应的数据... 反射是.NET中的重要机制,通过反射,可以在运行时获得程序或程序集中每一个类型(包括类、结构、委托、接口和枚举等)的成员和成员的信息。有了反射,即可对每一个类型了如指掌。另外我还可以直接创建对象,即使这个对象的类型在编译时还不知道。 二、反射的使用 平时我们的写法是先引用命名空间(dll),然后new一个对象,通过这个对象调用其中的字段或方法,通过反射,我们可以不用添加dll来实现效果。 1.首先我们在C#中创建一个Testdll类 打包dll,内容如下 using Sy. http://www.cnblogs.com/Laser_Lu/archive/2004/08/01/29171.html反射可以通过FieldInfo.SetValue设置任何字段的值。 using System; using System.Reflection; using System.Globalization;  public class MyClass {     private