Рассмотрите возможность использования ToLookup
, а не ToDictionary
. Lookups работают естественным образом с linq и общим кодом в целом, будучи неизменными и выставляя очень простой API. Кроме того, я бы инкапсулировал разбор в структуру EventLogLine
.
В результате код будет выглядеть следующим образом:
IEnumerable<string> lines;
ILookup<string, EventLogLine> lookup =
lines.Select(EventLogLine.Parse).ToLookup(evtLine => evtLine.EventName);
Пример потребитель:
if(lookup["HorribleEvent"].Any())
Console.WriteLine("OMG, Horrible!");
foreach(var evt in lookup["FixableEvent"])
FixIt(evt);
var q = from evtName in relevantEventNames
from evt in lookup[evtName]
select MyProjection(evt);
Обратите внимание, что вам не нужно, чтобы проверить ключ-существование, в отличии от Словаря :
if(dictionary.ContainsKey("HorribleEvent")) //&& dictionary["HorribleEvent"].Any() sometimes needed
Console.WriteLine("OMG, Horrible!");
if(dictionary.ContainsKey("FixableEvent"))
foreach(var evt in lookup["FixableEvent"])
FixIt(evt);
var q = from evtName in relevantEventNames.Where(dictionary.ContainsKey)
from evt in dictionary[evtName]
select MyProjection(evt);
Как вы можете заметить, работа со словарем, содержащим значения IEnumerable, tle triction - ILookup - это то, что вы хотите!
Наконец, модифицированный EventLogLine
:
public struct EventLogLine {
public string EventName { get; private set; }
public string Message { get; private set; }
public DateTime Date { get; private set; }
public static EventLogLine Parse(string line) {
var splitline = line.Split('|');
if(splitline.Length != 3) throw new ArgumentException("Invalid event log line");
return new EventLogLine {
EventName = splitline[0],
Message = splitline[1],
Date = DateTime.Parse(splitline[2]),
};
}
}