I have a Class with a List of objects, and those objects contain a list which has lists to objects in the first class, and I'm trying to quickly index them. Simplified:
class Person
{
public IEnumberable<HistoricalEvent> Events
{
get
{
return World.HistoricalEvents.Values.Where(x=>x.PeopleInvolved.Contains(this));
}
}
}
Also
class HistoricalEvent
{
public virtual IEnumerable<HistoricalFigure> PeopleInvolved
{
get { return Enumerable.Empty<People>(); }
}
...
}
and a subclass
class HistoricalEventSubclass : HistoricalEvent
{
Person person1 = new Person("Alice");
Person person2 = new Person("Bob");
public override IEnumerable<Person> PeopleInvolved
{
get
{
yield return person1;
yield return person2;
}
}
...
}
The Events class is called from a method using: frm.grpHistoricalFigureEvents.FillListboxWith(frm.lstHistoricalFigureEvents, Events);
internal static void FillListboxWith(this GroupBox groupbox, ListBox listbox, IEnumerable<object> objects)
{
if (objects == null || !objects.Any())
{
groupbox.Visible = false;
return;
}
groupbox.Visible = true;
listbox.BeginUpdate();
listbox.Items.Clear();
listbox.Items.AddRange(objects.ToArray());
listbox.EndUpdate();
listbox.SelectedIndex = 0;
var title = groupbox.Text.Split('(')[0].Trim();
groupbox.Text = string.Format("{0} ({1})", title, listbox.Items.Count);
}
The problem is that calling Events takes a long time (as World.HistoricalEvents can be a very big List). Is there a more time-efficient way of doing this?
Part of the slowdown is that Events is converted ToArray() and shoved into a listbox, and so I'll also be pursuing an alternative such as a listbox which can handle an IEnumberable directly.
Equals
andGetHashCode
on Person and changingPeopleInvoled
to be ISet<T>. Then, use a HashSet<T> for the underlying implementation. This makes more sense from a domain perspective, as a person's involvement with an event is binary - it makes no sense that they would appear twice. \$\endgroup\$