Список совпадений <string>в список <object>с использованием LINQ? - PullRequest
2 голосов
/ 16 июня 2019

Предположим, у нас есть список ввода со следующими значениями (все являются строками):

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 хранятся в формате, указанном в ListB.Если один из них провалится, я бы хотел создать специальное исключение.Что-то вроде

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

Я могу только представить себе очень уродливое решение для циклов for, множества приведений / преобразований и копирования.Есть ли в этом элегантное решение?

Ответы [ 3 ]

1 голос
/ 16 июня 2019

Вы можете сделать следующее с 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 гарантирует, что вам не придется преобразовывать весь список, если в списке ранее есть исключение.

1 голос
/ 16 июня 2019

Вы можете Zip списки вместе, а затем использовать Convert.ChangeType Метод

Возвращает объект указанного типа, значение которого эквивалентноуказанный объект.

Будет выдано исключение следующих типов

  • InvalidCastException Это преобразование не поддерживается.-или- значение равно нулю, а тип преобразования - тип значения.-или- значение не реализует интерфейс 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);
   }
}

Полная демонстрация здесь

Небольшая заметка : Технически говоряэто не кастинг сам по себе, это изменение / преобразование типа

0 голосов
/ 16 июня 2019

Хорошо, если вы хотите избежать 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]);

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...