c#使用一个变量值从固定列表中设置第二个

我在 ac# .net windows form 应用程序中解析一个 CSV 文件,将每一行放入我创建的类中,但是我只需要访问一些列并且所采用的文件不是标准化的。也就是说,存在的字段数可能不同,并且列可以出现在任何列中。


CSV 示例 1:


Position, LOCATION, TAG, NAME, STANDARD, EFFICIENCY, IN USE,,

1, AFT-D3, P-D3101A, EQUIPMENT 1, A, 3, TRUE

2, AFT-D3, P-D3103A, EQUIPMENT 2, B, 3, FALSE

3, AFT-D3, P-D2301A, EQUIPMENT 3, A, 3, TRUE

...

CSV 示例 2:


Position, TAG, STANDARD, NAME, EFFICIENCY, LOCATION, BACKUP, TESTED,,

1, P-D3101A, A, EQUIPMENT 1, 3, AFT-D3, FALSE, TRUE

2, P-D3103A, A, EQUIPMENT 2, 3, AFT-D3, TRUE, FALSE

3, P-D2301A, A, EQUIPMENT 3, 3, AFT-D3, FALSE, TRUE

...

正如你所看到的,我永远不会知道我必须分析的文件的格式,我唯一确定的是它总是包含我需要的几列。


我对此的解决方案是要求用户输入所需的列并将其设置为字符串,使用他们的条目将其转换为相应的整数,然后我可以将其用作位置。


string standardInpt = "";

string nameInpt = "";

string efficiencyInpt = "";

然后用户将输入一个从 A 到 ZZ 的值。


int standardLocation = 0;

int nameLocation = 0;

int efficiencyLocation = 0;

提交表单时。整数通过运行 if else... 语句获得最终值:


if(standard == "A")

{

  standardLocation = 0;

}

else if(standard == "B") 

{

  standardLocation = 1;

}

...

等一直运行到 if VAR1 == ZZ 然后对 VAR2 和 VAR3 等重复代码。


我的课程部分看起来像:


class Equipment

{

  public string Standard { get; set;}

  public string Name { get; set; }

  public int Efficiency { get; set; }


  static Equipment FromLine(string line)

  {

     var data = line.split(',');


     return new Equipment()

     {

      Standard = data[standardLocation],

      Name = [nameLocation],

      Efficiency = int.Parse(data[efficiencyLocation]),

     };

   }

}

我有更多的代码,但我认为这突出了我将使用变量来设置索引的地方。


我对此很陌生,我希望必须有一种更好的方法来实现这一点,而不必编写太多可能过多的重复 If Else 逻辑。我正在考虑某种查找表,但我无法弄清楚如何实现这一点,任何关于我可以查看的指针?


有只小跳蛙
浏览 150回答 3
3回答

慕田峪4524236

您可以使用反射和属性。将您的样本,分开写入DisplayName属性。首先调用GetIndexescsv 头字符串作为参数,获取类属性和 csv 字段的映射字典。然后调用FromLine每一行和你刚刚得到的映射字典。class Equipment{&nbsp; &nbsp; [DisplayName("STND, STANDARD, ST")]&nbsp; &nbsp; public string Standard { get; set; }&nbsp; &nbsp; [DisplayName("NAME")]&nbsp; &nbsp; public string Name { get; set; }&nbsp; &nbsp; [DisplayName("EFFICIENCY, EFFI")]&nbsp; &nbsp; public int Efficiency { get; set; }&nbsp; &nbsp; // You can add any other property&nbsp; &nbsp; public static Equipment FromLine(string line, Dictionary<PropertyInfo, int> map)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var data = line.Split(',').Select(t => t.Trim()).ToArray();&nbsp; &nbsp; &nbsp; &nbsp; var ret = new Equipment();&nbsp; &nbsp; &nbsp; &nbsp; Type type = typeof(Equipment);&nbsp; &nbsp; &nbsp; &nbsp; foreach (PropertyInfo property in type.GetProperties())&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int index = map[property];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; property.SetValue(ret, Convert.ChangeType(data[index],&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; property.PropertyType));&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return ret;&nbsp; &nbsp; }&nbsp; &nbsp; public static Dictionary<PropertyInfo, int> GetIndexes(string headers)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var headerArray = headers.Split(',').Select(t => t.Trim()).ToArray();&nbsp; &nbsp; &nbsp; &nbsp; Type type = typeof(Equipment);&nbsp; &nbsp; &nbsp; &nbsp; var ret = new Dictionary<PropertyInfo, int>();&nbsp; &nbsp; &nbsp; &nbsp; foreach (PropertyInfo property in type.GetProperties())&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var fieldNames = property.GetCustomAttribute<DisplayNameAttribute>()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .DisplayName.Split(',').Select(t => t.Trim()).ToArray();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < headerArray.Length; ++i)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!fieldNames.Contains(headerArray[i])) continue;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ret[property] = i;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return ret;&nbsp; &nbsp; }}

开满天机

您可以通过在标题中查找列的索引来使其自动化,然后使用它们从其余行的正确位置读取值:class EquipmentParser {&nbsp; &nbsp; public IList<Equipment> Parse(string[] input) {&nbsp; &nbsp; &nbsp; &nbsp; var result = new List<Equipment>();&nbsp; &nbsp; &nbsp; &nbsp; var header = input[0].Split(',').Select(t => t.Trim().ToLower()).ToList();&nbsp; &nbsp; &nbsp; &nbsp; var standardPosition = GetIndexOf(header, "std", "standard", "st");&nbsp; &nbsp; &nbsp; &nbsp; var namePosition = GetIndexOf(header, "name", "nm");&nbsp; &nbsp; &nbsp; &nbsp; var efficiencyPosition = GetIndexOf(header, "efficiency", "eff");&nbsp; &nbsp; &nbsp; &nbsp; foreach (var s in input.Skip(1)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var line = s.Split(',');&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result.Add(new Equipment {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Standard = line[standardPosition].Trim(),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Name = line[namePosition].Trim(),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Efficiency = int.Parse(line[efficiencyPosition])&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return result;&nbsp; &nbsp; }&nbsp; &nbsp; private int GetIndexOf(IList<string> input, params string[] needles) {&nbsp; &nbsp; &nbsp; &nbsp; return Array.FindIndex(input.ToArray(), needles.Contains);&nbsp; &nbsp; }}

慕后森

如果有帮助,试试这个:&nbsp; &nbsp; public int GetIndex(string input)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; input = input.ToUpper();&nbsp; &nbsp; &nbsp; &nbsp; char low = input[input.Length - 1];&nbsp; &nbsp; &nbsp; &nbsp; char? high = input.Length == 2 ? input[0] : (char?)null;&nbsp; &nbsp; &nbsp; &nbsp; int indexLow = low - 'A';&nbsp; &nbsp; &nbsp; &nbsp; int? indexHigh = high.HasValue ? high.Value - 'A' : (int?)null;&nbsp; &nbsp; &nbsp; &nbsp; return (indexHigh.HasValue ? (indexHigh.Value + 1) * 26 : 0) + indexLow;&nbsp; &nbsp; }
打开App,查看更多内容
随时随地看视频慕课网APP