0

对编程相当陌生。我只是想不通如何让它反向工作。我有一个保存方法和一个打开方法。节省:

IDictionary<string, IDictionary<string, object>> pluginStates = new Dictionary<string, IDictionary<string, object>>();
signaller.RaiseSaveRequest(pluginStates); <--goes out and gets packed plugins

//loop through plugins to get values and types
//holds all of the plugin arrays
Dictionary<string, object> dictProjectState = new Dictionary<string, object>();

foreach (KeyValuePair<string,IDictionary<string,object>> plugin in pluginStates)
{ 
    //holds jsonRepresented values
    Dictionary<string, object> dictJsonRep = new Dictionary<string, object>(); 
    //holds object types
    Dictionary<string, object> dictObjRep = new Dictionary<string, object>(); 
    object[] arrayDictHolder = new object[2];  //holds all of the dictionaries
    string pluginKey = plugin.Key;
    IDictionary<string, object> pluginValue = new Dictionary<string, object>(); 
    pluginValue = plugin.Value;

    foreach (KeyValuePair<string, object> element in pluginValue)
    {
        string jsonRepresentation = JsonConvert.SerializeObject(element);
        object objType = element.Value.GetType().ToString();
        dictJsonRep.Add(element.Key, jsonRepresentation);
        dictObjRep.Add(element.Key, objType);
    }
    arrayDictHolder[0] = dictJsonRep;
    arrayDictHolder[1] = dictObjRep;
    dictProjectState.Add(pluginKey, arrayDictHolder);
}

JsonSerializer serializer = new JsonSerializer();
using (StreamWriter sw = new StreamWriter(strPathName))
using (JsonWriter writer = new JsonTextWriter(sw))
{
     serializer.Serialize(writer, dictProjectState);
}

因此,当有人保存时,事件处理程序会发出并获取每个插件的 packedState,并将其添加到字典 pluginStates 中。然后,我遍历 pluginStates 中的每个插件,将值的键和 json 字符串版本添加到 1 个字典,将键、对象类型添加到另一个字典,将这两个字典添加到数组中,然后打包一个包含pluginKey 和每个插件的数组。推理:在反序列化时,我遇到了从 JArray 到类型 DataTable 以及字典中的其他类型的问题,这些类型在打开时被传递回插件以解压。我试图弄清楚如何扭转这一点,以便当用户打开项目时,我有 dictProjectState 并且需要通过代码将它一直带回以最终得到 1 个包含插件的字典。我如何在公开场合镜像这个保存?谢谢!

4

1 回答 1

0

我相信当你在 open 函数中反序列化时,你应该得到一个可以转换为Dictionary<string, object>.

该字典的键将是您最终字典中插件的名称(yoru save 方法中的插件键)。值应该是object[] arrayDictHolder对象。您可以将它们转换为object[]然后获取内部的两个值(保存函数中的 dictJsonRep 和 dictObjRep)。

一旦这些值都转换为Dictionary<string, object>(),您可以遍历其中一个中的 KeyValuePairs,并使用这些对中的键来获取另一个字典中的值存储。

代码将类似于以下内容:

var pluginStates = new Dictionary<string, IDictionary<string, object>>();

var dictProjectState = jsonSerializer.Deserialize(reader) as Dictionary<string, object>;

foreach(var projectStatePair in dictProjectState)
{
    string pluginKey = projectStatePair.Key;
    var pluginValues = new Dictionary<string, object>();
    object[] arrayDictHolder = projectStatePair.Value as object[];
    var dictJsonRep = arrayDictHolder[0] as Dictionary<string, object>;
    var dictObjRep =  arrayDictHolder[1] as Dictionary<string, object>;
    foreach(var JsonRepPair in dictJsonRep)
    {
        string jsonRepresentation = JsonRepPair.Value;
        // We know both dictionaries have the same keys, so
        // get the objType for this JsonRepresentation
        object objType = dictObjRep[JsonRepPair.Key];
        // Since you're serializing objType to a string, you'll need
        // to get the actual Type before calling DeserializeObject.
        Type jsonType = System.Type.GetType(objType as string);
        object value = JsonConvert.DeserializeObject( jsonRepresentation, jsonType );
        pluginValues.Add( JsonRepPair.Key );
    }
    pluginStates.Add( pluginKey, pluginValues );
}

注意:您当前element.Value.GetType().ToString();在保存函数中将 objType 设置为。element.Value.GetType();在尝试反序列化之前,您将需要更新 save() 以将其设置为或将类型字符串转换回实际类型。

注意:我对 Json 库不是很熟悉。上面的代码专注于从反序列化的结果中创建你的 pluginStates 字典。您将需要处理 JsonSerializer 的创建,并确保在反序列化它们后关闭所有流。您可能还需要调整实际的反序列化调用以获得所需的结果。

更新:添加了 objType 到实际 System.Type 对象的转换。

于 2012-06-12T13:54:30.360 回答