如何将字符串列表转换为每个字符都有一个属性的匿名类型

Avr*_*oel 0 c# dynamic expandoobject

假设我有一个List<string>,其中每个字符串的长度相同。这个长度事先是不知道的,只能通过在运行时检查字符串的 Length 属性(比如第一个,因为它们的长度都相同)来确定。

我想要的是最终得到一组匿名对象,每个对象都有属性 C1、C2 等,每个角色一个。

因此,如果列表中的第一个字符串是“abcd”,那么结果列表中的第一个匿名对象将是...

{
  C1 = "a",
  C2 = "b",
  C3 = "c",
  C4 = "d"
}
Run Code Online (Sandbox Code Playgroud)

这可能吗?我一直在与动态和 ExpandoObjects 作斗争,但还没有设法使它们中的任何一个工作。主要问题似乎是事先不知道属性名称。

我尝试做类似的事情(循环)......

d["C" + i] = str.[j];
Run Code Online (Sandbox Code Playgroud)

...但这不起作用,因为它认为我正在尝试使用数组索引。我收到运行时异常“无法将 [] 索引应用于‘System.Dynamic.ExpandoObject’类型的表达式”

这可以做到吗?

Ser*_*kiy 5

您可以将其视为ExpandoObject字典,其中属性名称为键,值作为属性值。使用这个简单的扩展方法,您可以创建一个 ExpandoObject 并使用从源字符串生成的属性填充它:

public static ExpandoObject ToExpando(this string s)
{
    var obj = new ExpandoObject();
    var dictionary = obj as IDictionary<string, object>;       
    var properties = s.Distinct().Select((ch, i) => new { Name = $"C{i+1}", Value = ch });

    foreach (var property in properties)
        dictionary.Add(property.Name, property.Value);

    return obj;
}
Run Code Online (Sandbox Code Playgroud)

用法:

var source = new List<string> { "bob", "john" };
var result = source.Select(s => s.ToExpando());
Run Code Online (Sandbox Code Playgroud)

输出:

[
  {
    "C1": "b",
    "C2": "o"
    // NOTE: If C3 = "b" is required here, than remove Distinct() in extension method
  },
  {
    "C1": "j",
    "C2": "o",
    "C3": "h",
    "C4": "n"
  }
]
Run Code Online (Sandbox Code Playgroud)