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

时间:2019-06-16 01:17:14

标签: c# arrays linq casting

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

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中的类型列表进行匹配来验证ListA中的所有值是否都正确。两个列表的长度相同。

如果是,我想获取一个List作为返回值,其中ListA的所有值都以ListB中指定的格式存储。 如果一次转换失败,我希望能够引发一个自定义异常。

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

我只能想象一个非常丑陋的解决方案,其中包含for循环,大量强制转换/转换和复制。有解决方案吗?

3 个答案:

答案 0 :(得分:1)

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

  

返回指定类型的对象,该对象的值等于a   指定的对象。

它将引发以下类型的异常

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

  • FormatException的值不是由conversionType识别的格式。

  • OverflowException值表示一个超出conversionType范围的数字。

  • ArgumentNullException conversionType为空。

示例

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);
   }
}

Full Demo Here

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

答案 1 :(得分:1)

您可以对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中进行转换,可以确保如果列表中较早的地方没有异常,则不必转换整个列表。

答案 2 :(得分:0)

好吧,如果您想避免使用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]);

}