2010-06-29 3 views
9

Итак, вопрос в том, что у меня есть для каждого цикла, который я использую в настоящее время для извлечения данных из запроса XML-файла, который затем помещается в строку; как так:Как получить foreach для запуска один раз

foreach (var value in dateQuery) 
       date = value.Element("HistoryCreation").Value; 

Я знаю, на самом деле (на основе образом файл хранит значения XML и запрос используется), что будет только одно значение в dateQuery.

Таким образом, я хотел бы знать (в целях повышения эффективности моей программы и обучения тому, как лучше кодировать), есть ли лучший способ сделать это или сделать foreach единственным способом?

+0

Не могу поверить, что потребовалось так много времени (3 минуты), чтобы ответить на этот вопрос. – xcud

+0

Потребуется минутка для появления вопросов. Особенно на первой странице (не когда вы нажимаете «Вопросы») – tster

ответ

18

Вы могли бы использовать:

dateQuery.First().Element("HistoryCreation").Value 

Это не будет ошибкой, если есть несколько элементов в запросе. Если вы хотите, чтобы потерпеть неудачу, если есть несколько элементов, а затем использовать Single

8
date = dateQuery.Single().Element("HistoryCreation").Value; 
7

Если вы используете .NET 3.5 или более позднюю версию, вы можете использовать метод расширения Enumerable.Single:

var value = dateQuery.Single(); 
date = value.Element("HistoryCreation").Value; 

Тогда, если ваше предположение «там будет только одно значение в dateQuery 'неверно, это вызовет исключение.

+0

tster: Я удалил его - понятно, что он использует 3.5 из использования var. –

2

Не можете ли вы просто получить первый индекс dateQuery?

date = dateQuery[0].Element("HistoryCreation").Value; 
+0

Нет, если это IEnumerable tster

+0

@tster - Согласен, но это не подразумевается в вопросе. – Oded

+0

Вам нужно будет проверить, что dateQuery имеет хотя бы один элемент, иначе вы получите исключение индекса за пределами диапазона. – JLWarlow

2
dateQuery.First().Element("HistoryCreation").Value 

, если вы можете использовать LINQ

+2

Черт, вам действительно нужно быть быстрым на ничью здесь! – Pharabus

+0

Я согласен, эти ответы были в порядке; и они пришли так быстро. : / –

2

Вы можете попробовать

var theValue = dateQuery.FirstOrDefault(); 
if (theValue != null) 
{ 
    data = theValue.Element("HistoryCreation").Value; 
} 
else 
{ 
     //Deal with the fact that there is no data 
} 

Вы можете использовать .Первый() или .Single() , но если в dataQuery ничего нет, будет выбрано исключение.

5

Ответ от Марка, безусловно, лучший, но я поставил шахту для иллюстрации цикла foreach.

foreach (var value in dateQuery) { 
    date = value.Element("HistoryCreation").Value; 
    break; // break current loop 
} 
1

, что следует сделать трюк:

using System.Linq; 

dateQuery.Single(); 
4

Emmanual, если вы знаете, что вам нужно сделать только что-то один раз, вы не должны использовать цикл.

4

Подводя итог:

  • использование First(), если вы хотите, первый элемент и знать, что есть по крайней мере один (или более) элементов в последовательности.
  • использование FirstOrDefault(), если последовательность может иметь любое количество элементов
  • использовать Single(), если последовательность может иметь ровно один пункт
  • использовать SingleOrDefault(), если последовательность всегда имеет ноль или один элемент

Обратите внимание, что существует также версия этих, которые принимают предикаты, так что вы можете сократить

var result = sequence.Where(predicate).First(); 

к

-
var result = sequence.First(predicate); 
Смежные вопросы