C# 从另一个具有字典的对象构造动态对象<;字符串,对象>;具有可变键值对的属性

C# 从另一个具有字典的对象构造动态对象<;字符串,对象>;具有可变键值对的属性,c#,dynamicobject,C#,Dynamicobject,我试图从包含一些静态属性的现有对象中整理属性。该对象还包含一个带有键值对的字典。这些键值对应该作为属性动态添加到我正在创建的新对象中 这是源对象的设置: 公共类MyClass { 公共字符串PropA{get;set;} 公共字符串PropB{get;set;} 公共字符串PropC{get;set;} 公共IDictionary PropD{get;set;} } 公共类名称值对 { 公共字符串名称{get;set;} 公共字符串值{get;set;} } 这是我创建对象列表的地方: vo

我试图从包含一些静态属性的现有对象中整理属性。该对象还包含一个带有键值对的字典。这些键值对应该作为属性动态添加到我正在创建的新对象中

这是源对象的设置:

公共类MyClass
{
公共字符串PropA{get;set;}
公共字符串PropB{get;set;}
公共字符串PropC{get;set;}
公共IDictionary PropD{get;set;}
}
公共类名称值对
{
公共字符串名称{get;set;}
公共字符串值{get;set;}
}

这是我创建对象列表的地方:

void Main()
{

    var data = new List<MyClass>
    {
        new MyClass {PropA = "A1", PropB = "B1", PropC = "C1", PropD = new Dictionary<string, NameValuePair>
        {
            { "Code11", new NameValuePair {Name = "PropD11", Value = "V11"}},
            { "Code12", new NameValuePair {Name = "PropD12", Value = "V12"}}
        }},
        new MyClass {PropA = "A2", PropB = "B2", PropC = "C2", PropD = new Dictionary<string, NameValuePair>
        {
            { "Code21", new NameValuePair {Name = "PropD21", Value = "V21"}},
            { "Code22", new NameValuePair {Name = "PropD22", Value = "V22"}},
        }},
        new MyClass {PropA = "A3", PropB = "B3", PropC = "C3", PropD = new Dictionary<string, NameValuePair>
        {
            { "Code12", new NameValuePair {Name = "PropD12", Value = "V31"}},
            { "Code21", new NameValuePair {Name = "PropD21", Value = "V32"}},
        }},
    };
//Extract column names from static properties
    var staticColumns = typeof(MyClass).GetProperties().Where(n => n.PropertyType == typeof(string)).Select(p => p.Name);

//Extract column names from the dictionary
    var dynamicColumns = data.Where(c => c.PropD.Any()).Select(c => c.PropD).SelectMany(c => c.Values.Select(v => v.Name)).Distinct().ToList();

//Combine to get a new list of columns 
    var columns = staticColumns.Union(dynamicColumns);

//Create object using columns

//Copy values from data to construct the new object.    
}

假设您可能的属性名称是静态的,下面是一个答案类:

public class AnsClass {
    public string PropA { get; set; }
    public string PropB { get; set; }
    public string PropC { get; set; }

    public string PropD11 { get; set; }
    public string PropD12 { get; set; }
    public string PropD21 { get; set; }
    public string PropD22 { get; set; }
}
下面是一个LINQ语句,用于创建它们的列表:

var ans = data.Select(d => new AnsClass {
                    PropA = d.PropA,
                    PropB = d.PropB,
                    PropC = d.PropC,
                    PropD11 = d.PropD.Values.FirstOrDefault(v => v.Name == "PropD11")?.Value,
                    PropD12 = d.PropD.Values.FirstOrDefault(v => v.Name == "PropD12")?.Value,
                    PropD21 = d.PropD.Values.FirstOrDefault(v => v.Name == "PropD21")?.Value,
                    PropD22 = d.PropD.Values.FirstOrDefault(v => v.Name == "PropD22")?.Value,
                })
                .ToList();
如果
PropD
的成员是动态的,您可以使用以下方法来创建
ExpandoObjects
,但是您最好只使用
MyClass
的方式—它已经有了最好的设计

var ans2 = new List<dynamic>();
foreach (var d in data) {
    dynamic eo = new ExpandoObject();
    eo.PropA = d.PropA;
    eo.PropB = d.PropB;
    eo.PropC = d.PropC;
    var deo = (IDictionary<string,object>)eo;
    foreach (var dp in d.PropD.Values)
        deo.Add(dp.Name, dp.Value);
    ans2.Add(eo);
}
var ans2=新列表();
foreach(数据中的var d){
动态eo=新的ExpandooObject();
eo.PropA=d.PropA;
eo.PropB=d.PropB;
eo.PropC=d.PropC;
var deo=(i词典)eo;
foreach(以d.PropD.值表示的var dp)
deo.Add(dp.Name,dp.Value);
ans2.添加(eo);
}

你在寻求什么帮助?我如何动态添加属性PropD11、PropD12、PropD21和PropD22,使动态对象看起来像表?我不知道“动态对象”在这里的具体含义。如果将
ExpandoObject
引用为
dynamic
,则此处不适用,因为属性名称作为运行时字符串而不是编译时符号保存。使用ExpandooObject来实现这一点是荒谬的。为什么不使用字典或数据表?@user1145404啊,但这正是你在
MyClass
中所拥有的,也是
字典的确切用途。这听起来像是一场灾难。你到底想完成什么?使用
MyClass
这样做有什么限制?为什么它们需要是单独的属性?与仅在
PropD
中访问它们相比,这有什么好处?或者根据每个
NameValue
PropD
更改为
Dictionary
,然后忽略这些代码?谢谢。但是,PropD值是动态的。直到运行时我才知道名称。@user1145404我添加了代码来创建
ExpandoObject
s。谢谢。ExpandoObject的解决方案解决了我的问题。
var ans2 = new List<dynamic>();
foreach (var d in data) {
    dynamic eo = new ExpandoObject();
    eo.PropA = d.PropA;
    eo.PropB = d.PropB;
    eo.PropC = d.PropC;
    var deo = (IDictionary<string,object>)eo;
    foreach (var dp in d.PropD.Values)
        deo.Add(dp.Name, dp.Value);
    ans2.Add(eo);
}