首页 > 解决方案 > 动态添加键,值解析数组放入 Object.property = value 模式

问题描述

我有一个对象定义如下:

public class Variable
{
    public string varName { get; set; }
    public double varVal { get; set; }
    public double varParam { get; set; }

    public Variable(string varName1, double varVal1 = 1, double varParam1 = 0)
    {
        varName = varName1;
        varVal = varVal1;
        varParam = varParam1;
    }
}

我在一个列表中有这个对象,需要由父类中的许多方法访问,如下所示:

public static List<Variable> variableList = new List<Variable>();

我在一个文本文件上有一个输入,我用.Split(",")它以任何顺序放入字符串数组,并且可能缺少键值(除了名称):

varName,Test,varVal,1.0101,varParam,3.03

所以在我的代码中,在我使用.Split(",")这个文本行之后:

string readKeyvalue[] = { "varName","Test","varVal","1.0101","varParam","3.03" }

我必须强调,varName文本文件中只需要密钥对,所有这些都可以按任何顺序排列。我想将它们放入结构中的对象属性中,如下所示(伪代码):

variableList[0].varName == Test
variableList[0].varVal == 1.0101
variableList[0].varParam == 3.03

我之前的努力未能通过对数组进行排序(有效)并使用以下内容来实现这一点,这可以在我之前的问题中参考。此行适用于缺少 的情况varVal,但已排序为 的字符串数组varName,Test,varParam,3.03

materialList.Add(new Material(sortedVals[1]) { $sortedVals[2] = Convert.ToDouble(sortedVals[3]) } ) ;

如您所见,这不起作用,因为sortedVals[2]编译器不将其识别为成员声明符,而且我找不到任何方法(没有 2-3 个更多的类,只是为了将字符串转换为属性,然后强行通过吨代码)将所有可用值分配给属性,同时跳过缺失的值。

所以澄清一下,我找不到一种方法来将可用属性分配给一个对象,同时忽略任何丢失的对象,而无需在每种情况下进行硬编码(当我有一个具有 10-12 个属性的对象时,这将非常困难)。

如果有人有任何智慧,我将非常感激!

标签: c#object

解决方案


因此,如果我理解您的问题,一种方法是将您的输入字符串解析为字典。像这样的东西:

var input = "varName,Test,varVal,1.0101,varParam,3.03";

var grouped = input.Split(',').Select((str,idx) => new {str, idx})
    .GroupBy(g => g.idx / 2)
    .Select(g => g.Select(s => s.str).ToArray());
Console.WriteLine(grouped.First().ToString());
var dictionary = grouped.ToDictionary(g => g[0], k => k[1]);

这个想法是拆分您的字符串,然后将其分组为成对的值(按索引/ 2 分组,这将截断,因为它是整数除法)。从那里您可以将这些对转换为数组(具有两个值),然后转换为一个字典,该字典键控每对的第一个值。

然后你可以使用数据库键来填充你的对象,测试它们的存在:

variableList[0].varName = dictionary.TryGetValue("varName", out var s) ? s : null;
variableList[0].varVal = dictionary.TryGetValue("varVal", out var s) ? double.TryParse(s, out var d) ? d : 0.0 : 0.0;
variableList[0].varParam = dictionary.TryGetValue("varParam", out var s) ? double.TryParse(s, out var d) ? d : 0.0;

如果字符串格式错误,我使用double.TryParse并回退到 0,但您可能希望以不同的方式实际处理。


推荐阅读