<string> <object> 使用 LINQ 将列表与列表匹配?



假设我们有一个包含以下值的输入列表(都是字符串(:

var listA = new List<string>();
listA.Add("test");
listA.Add("123");
listA.Add("5.7");

我们还得到了第二个列表:

var listB = new List<object>();
listB.Add(typeof(string));
listB.Add(typeof(int));
listB.Add(typeof(float));

我想通过将 ListA 中的所有值与 ListB 中的类型列表匹配来验证其格式是否正确。两个列表将具有相同的长度。

如果是,我想获取一个 List 作为返回值,其中 ListA 的所有值都以 ListB 中指定的格式存储。如果一个会议失败,我希望能够抛出一个自定义异常。类似的东西

throw new MyException($"Failed to convert value {valueX} to {type}");

我只能想象一个非常丑陋的解决方案,包括 for 循环、大量投射/转换和复制。有没有一个优雅的解决方案?

您可以使用 Zip 执行以下操作。

var result = listA.Zip(listB,(value,type)=> 
                        { 
                           try{return Convert.ChangeType(value,(Type)type);} 
                           catch{throw new Exception($"Cannot cast between value {value} to Type {type}");}
                        });

通过在 Zip 中进行转换,将确保在列表中较早出现异常时不必转换整个列表。

您可以将列表压缩在一起,然后使用 Convert.ChangeType 方法

返回指定类型的对象,其值等效于指定的对象。

它将引发以下类型的异常

    InvalidCastException 不支持此转换。 -或 - 值为
  • 空,转换类型为值类型。 -或 - 值不实现 IConvertible 接口。

  • FormatException值不是转换类型识别的格式。

  • OverflowException值表示超出转换类型的数字。

  • ArgumentNullException转换类型为空。

var listA = new List<string> { "test", "123", "5.7" };
var listB = new List<Type> { typeof(string), typeof(int), typeof(int) };
    
var combined = listA.Zip(listB, (s, type) => (Value :s, Type:type));
foreach (var item in combined)
{
   try
   {
      Convert.ChangeType(item.Value, item.Type);
   }
   catch (Exception ex)
   {
      throw new InvalidOperationException($"Failed to cast value {item.Value} to {item.Type}",ex);
   }
}

完整演示在这里

旁注:从技术上讲,这不是强制转换本身,而是更改/转换类型

好的,如果你想

避免forloop并使用linq来做,仍然是可能的

这是我必须的

var listA = new List<string>();
    listA.Add("test");
    listA.Add("123");
    listA.Add("5.7");
   var listB = new List<Type>();
    listB.Add(typeof(string));
    listB.Add(typeof(int));
    listB.Add(typeof(float));
   var index =-1;
try{
var newList = listA.Select((x, i)=>  Convert.ChangeType(x, listB[(index = i)])).ToList();
}catch(Exception e){
 throw  new Exception("Failed to cast value "+listA[index]+" to "+listB[index]);
}

最新更新