如何获取 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按索引查询,第五步我们要取回文件信息。
注:
file
和 index
都是动态创建的属性,它们来自 JSON 数据。当然你可以从不同的来源获得ExpandoObject
。
- 使用
ExpandoObject
时,请注意 属性 名称中的任何拼写错误 不会 导致编译错误,但会导致 运行时间错误(并且仅当相关代码部分正在执行时)。
您可以 运行 LinqPad 或 Visual Studio 中的示例,但不要忘记添加 Newtonsoft.Json(作为 NUGET 包)。
首先我将 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按索引查询,第五步我们要取回文件信息。
注:
file
和index
都是动态创建的属性,它们来自 JSON 数据。当然你可以从不同的来源获得ExpandoObject
。- 使用
ExpandoObject
时,请注意 属性 名称中的任何拼写错误 不会 导致编译错误,但会导致 运行时间错误(并且仅当相关代码部分正在执行时)。
您可以 运行 LinqPad 或 Visual Studio 中的示例,但不要忘记添加 Newtonsoft.Json(作为 NUGET 包)。