2010-03-17 2 views
0

У меня есть ICollection, которого я знаю, будет только один член. В настоящее время я прохожу через него, зная, что цикл будет выполняться только один раз, чтобы получить значение. Есть ли более чистый способ сделать это?C#: Легкий доступ к элементу Singleton ICollection <>?

Я могу изменить объект persistentState для возврата отдельных значений, но это усложнит остальную часть интерфейса. Он захватывает данные из XML, и в большинстве случаев подходит ICollection.

// worldMapLinks ensured to be a singleton 
ICollection<IDictionary<string, string>> worldMapLinks = persistentState.GetAllOfType("worldMapLink"); 

string levelName = ""; //worldMapLinks.GetEnumerator().Current['filePath']; 

// this loop will only run once 
foreach (IDictionary<string, string> dict in worldMapLinks) // hacky hack hack hack 
{ 
    levelName = dict["filePath"]; 
} 

// proceed with levelName 
loadLevel(levelName); 

Вот еще один пример того же вопроса:

// meta will be a singleton 
ICollection<IDictionary<string, string>> meta = persistentState.GetAllOfType("meta"); 
foreach (IDictionary<string, string> dict in meta) // this loop should only run once. HACKS. 
{ 
    currentLevelName = dict["name"]; 
    currentLevelCaption = dict["teaserCaption"]; 
} 

Еще один пример:

private Vector2 startPositionOfKV(ICollection<IDictionary<string, string>> dicts) 
{ 
    Vector2 result = new Vector2(); 
    foreach (IDictionary<string, string> dict in dicts) // this loop will only ever run once 
    { 
     result.X = Single.Parse(dict["x"]); 
     result.Y = Single.Parse(dict["y"]); 
    } 

    return result; 
} 

ответ

4

Почему бы не использовать одинарную или FirstOrDefault методы расширения?

var levelName = worldMapLinks.Single().Value; 

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

+0

+1 Лучший ответ - «Один» - лучший выбор здесь. :) –

0

Если вы можете использовать LINQ-to-objects в своем классе, используйте метод расширения Single() в коллекции, если вы знаете, что будет ровно один член. В противном случае, если может быть ноль или один, используйте SingleOrDefault()

0

Почему у вас есть коллекция только с одним членом? Кажется, что реальный ответ должен состоять в том, чтобы лучше спроектировать вашу систему, а не полагаться на какой-либо метод для извлечения одного элемента из коллекции. Вы говорите, что это усложняет ситуацию, но как? Разве это не само решение? Можно ли изменить интерфейс, чтобы вернуть один элемент, если это применимо, и коллекцию в другом месте? Похоже, мне запах кода.

+0

Это определенно возможно, но использование ответа @ JaredPar кажется лучше пока. –

+0

Согласен. Просто кажется, что, если есть случай, когда вы ЗНАЕТЕ, вы получите только один элемент, это намек на то, что есть лучший семантический вариант. Могут быть другие случаи, когда большие коллекции возвращаются, но я думаю, что для них подходит другой метод. –

Смежные вопросы