Преобразование объекта T в список в C#

#c# #.net #generics #collections #casting

#c# #.net #общие сведения #Коллекции #Кастинг

Вопрос:

У меня глупая, но потрясающая проблема с приведением типов. Как вы можете видеть из кода, у меня есть переменная lprod_monthylReport, которая в зависимости от ytm значения может быть List<Monthly_Report> или просто Monthly_Report . Мне нужно, чтобы переменная имела одно и то же имя в обоих случаях.

 var lprod_monthlyReport = new List<Monthly_Report>;

if (ytm == true)
{
   lprod_monthlyReport = _ProductRep.GetSpecificArchiveReport(prod.Prod_ID, lmonth, lyear, item.item_ID);
}
else
   lprod_monthlyReport = _ProductRep.GetSpecificYTMReport(prod.Prod_ID, item.item_ID);
  

Проблема в том, что если я объявляю переменную внутри каждого раздела if (или else), компиляторы выдают ошибку, поскольку в ней говорится, что переменная уже объявлена в этом контексте.

Я уже пробовал приводить

 lprod_monthlyReport = (Monthly_Report) _ProductRep.GetSpecificArchiveReport(prod.Prod_ID, lmonth, lyear, item.Item_ID);
  

Но это не работает. Я также безуспешно пробовал использовать ключевое слово as.

Не могли бы вы, пожалуйста, помочь мне с этим? Спасибо

Франческо

Комментарии:

1. какой тип возвращают GetSpecificArchiveReport и GetSpecificYTMReport

2.Почему lprod_monthlyReport должно быть a List<Monthly_Report> , а не то, что возвращают ваши методы?

3. @Hath: спасибо за ваш ответ. GetSpecificArchiveReport возвращает объект Monthly_Report (он выполняет запрос LINQ с использованием Single ) GetSpecificYTMReport возвращает список<Monthly_Report> (запрос LINQ с использованием Where ).

4. @Rowland Shaw: спасибо за ваш ответ. Обратите внимание, что эти два метода отличаются не только сигнатурой

Ответ №1:

Это должно сработать: если у вас есть Monthly_Report просто добавьте его в список…

     List<Monthly_Report> lprod_monthlyReport;
    if (ytm == true)
    {
       lprod_monthlyReport  = new List<Monthly_Report>();
       lprod_monthlyReport.add(_ProductRep.GetSpecificArchiveReport(prod.Prod_ID, lmonth, lyear, item.item_ID));
    }
    else{
       lprod_monthlyReport = _ProductRep.GetSpecificYTMReport(prod.Prod_ID, item.item_ID));
    }
  

Комментарии:

1. Гениально, это то, что я искал! Большое спасибо. На самом деле я хотел внести небольшое улучшение. Вы можете объявить в начале переменную lprod_monthlyReport = new List<Monthly_Report>(); и удалить ее из блока if . В противном случае блок else работать не будет

2. @Francesco: если вы получаете List<Monthly_Report> из `GetSpecificYTMReport()’, почему это не должно работать?

3. простите, это работает. Не могли бы вы объяснить мне, почему вы создаете экземпляр объекта внутри if, а не при его объявлении?

Ответ №2:

Первая строка кода

 var lprod_monthlyReport = new List<Monthly_Report>;
  

означает, что переменная имеет тип, List<Monthly_Report> поэтому она не может содержать ни одного Monthly_Report объекта.

Этот код следует переработать, чтобы он работал по-другому, или чтобы этот метод возвращал a, List<Monthly_Report> содержащий только один Monthly_Report элемент.

Комментарии:

1. спасибо за ваш ответ. Обратите внимание, что эти два метода отличаются. Один возвращает список<Ежемесячный отчет> , другой — ежемесячный отчет

Ответ №3:

Важным моментом в var ключевом слове является то, что оно не означает «вариант». var используется компилятором для вывода типа, что означает, где вы объявляете:

 var something = new List<Something>();
  

…вы объявляете что-то типа List<Something> . Это означает, что вы не сможете затем выполнить:

 something = new Something();
  

… поскольку вы уже объявили это как нечто другое. var с точки зрения удобства использования — это синтаксический сахар. Компилятор (и движок Visual Studio intellisense) используют вывод типа, чтобы узнать, что something есть на самом List<Something> деле.

Ответ №4:

Увы, это не сработает.

Но вы могли бы в качестве альтернативы обернуть единственный экземпляр в список, если хотите. Затем вам нужно всего лишь заставить свой код работать с List<Monthly_Report> одним или несколькими Monthly_Report элементами.

Ответ №5:

объявить lprod_monthlyReport как «объект». Между is и Monthly_Report нет List<Monthly_Report> связи.

У вас возникнут проблемы, когда вы начнете использовать ‘lprod_monthlyReport’, потому что вы не будете знать, какого это типа, кроме object, ключевое слово ‘is’ может помочь вам тогда.

Учтите это и подумайте о реструктуризации вашего кода.

Комментарии:

1. неприменимо, потому что тогда мне нужно запросить переменные. Если я объявлю их как object, компилятор не найдет методы запроса

Ответ №6:

Попробуйте это

 List<Monthly_Report> lprod_monthlyReport;

if (ytm == true) 
{
    lprod_monthlyReport = _ProductRep.GetSpecificArchiveReport(prod.Prod_ID, lmonth, lyear, item.item_ID);
} 
else
{ 
   lprod_monthlyReport = new List<Monthly_Report>() 
    {
       _ProductRep.GetSpecificYTMReport(prod.Prod_ID, item.item_ID)
    };
}
  

Комментарии:

1. это не будет скомпилировано, вы не сможете определить тип var позже.

2. спасибо за ваш ответ. Однако вы не можете объявить переменную var без выполнения присваивания.