如何获取 expando 对象的价值 #

how get value on expando object #

首先我将 txt 文件读入一个文件夹,然后我用 expando 对象对对象进行水化。

但现在我想从这个对象中获取一些值来填充列表视图 (winforms)。

private void Form1_Load(object sender, EventArgs e)
{                  
    string pattern = "FAC*.txt";
    var directory = new DirectoryInfo(@"C:\TestLoadFiles");
    var myFile = (from f in directory.GetFiles(pattern)
                  orderby f.LastWriteTime descending
                  select f).First();

    hydrate_object_from_metadata("FAC",listBox3);
    hydrate_object_from_metadata("BL", listBox4);

    this.listBox3.MouseDoubleClick += new MouseEventHandler(listBox3_MouseDoubleClick);
    this.listBox1.MouseClick += new MouseEventHandler(listBox1_MouseClick);
}

void hydrate_object_from_metadata(string tag, ListBox listBox)
{
    SearchAndPopulateTiers(@"C:\TestLoadFiles", tag + "*.txt", tag);
    int count = typeDoc.Count(D => D.Key.StartsWith(tag));

    for (int i = 0; i < count; i++)
    {
        object ob = GetObject(tag + i);
        ///HERE I WOULD LIKE GET DATA VALUE FROM ob object
    }
}

Object GetObject(string foo)
{
    if (typeDoc.ContainsKey(foo))
        return typeDoc[foo];
    return null;
}

void SearchAndPopulateTiers(string path, string extention, string tag)
{
    DirectoryInfo di = new DirectoryInfo(path);
    FileInfo[] files = di.GetFiles(extention);

    int i = 0;
    foreach (FileInfo file in files)
    {
        var x = new ExpandoObject() as IDictionary<string, Object>;

        string[] strArray;
        string s = "";

        while ((s = sr.ReadLine()) != null)
        {
            strArray = s.Split('=');

            x.Add(strArray[0],strArray[1]);

        }

        typeDoc.Add(tag+i,x);
        i++;
    }
}

那么是否可以在 expando 对象上获取值?

dynamic eod = eo;

value = eod.Foo;

我正在这样做 generically/dynamically 所以没有在代码中包含实际字段名称的选项,最终以这种方式完成:

eo.Where(v => v.Key == keyNameVariable).Select(x => x.Value).FirstOrDefault();

可能是更好的方法,但它确实有效。

“LINQ”方式:

我写了一个简单的例子来向你展示这个想法。考虑以下代码(JSON 部分仅用于快速生成一些数据,然后将其转换为 expando 对象,有趣的部分从步骤 3 开始。):

// uses Newtonsoft.Json
void Main()
{
    // 1. prepare data as JSON string (just to have some data for demo)
    var rowData = "{\"rows\": ["
               
               + "{"
               + "\"index\":0,"
               + "\"file\":\"calc.exe\""
               + "},"
               
               + "{"
               + "\"index\": 1,"
               + "\"file\":\"cmd.exe\""
               + "}"
               
               + "]}";
    
    // display JSON string
    rowData.Dump();
    
    // 2. convert JSON string to expando object
    var expConverter = new ExpandoObjectConverter();
    dynamic exp = JsonConvert.DeserializeObject<ExpandoObject>(rowData, expConverter);
    
    // 3. convert to queryable list (so you can query the rows)
    var rows = (List<dynamic>)exp.rows;
    
    // 4. query it by selecting row with index==0
    var q = rows.Where(w => w.index == 0);
    
    // 5. getting the file property
    var fileName = q.Select(s => (string)s.file).First();

    // display result
    fileName.Dump();
    
}

现在,在提供 expando 对象(变量 exp,它是完全动态的)之后,下一步 (3.) 将其转换为我们可以查询的内容(此处为动态对象列表)。

然后第四步是使用LINQ按索引查询,第五步我们要取回文件信息。

注:

  • fileindex 都是动态创建的属性,它们来自 JSON 数据。当然你可以从不同的来源获得ExpandoObject
  • 使用 ExpandoObject 时,请注意 属性 名称中的任何拼写错误 不会 导致编译错误,但会导致 运行时间错误(并且仅当相关代码部分正在执行时)。

您可以 运行 LinqPad 或 Visual Studio 中的示例,但不要忘记添加 Newtonsoft.Json(作为 NUGET 包)。