There is no need to iterate through every web, Personnaly I even think its bad.
Instead, use the SPSiteDataQuery class
SPSiteDataQuery query = new SPSiteDataQuery();
// Query all Web sites in this site collection.
query.Webs = "<Webs Scope=\"SiteCollection\">";
//Ask for all lists created from the Calendar template.
query.Lists = "<Lists ServerTemplate=\"106\" />";
DataTable dtResults = site.RootWeb.GetSiteData(query);
String[] columns = {"ListId"};
DataTable dtDistinctResults = new DataView(dtResults).ToTable(true, columns);
foreach (DataRow oRow in dtDistinctResults .Rows)
{
SPWeb oWeb = site.OpenWeb(new Guid(oRow["WebId"].ToString()));
SPList oList = oWeb.Lists[new Guid(oRow["ListId"].ToString())];
//peprform your changes
}
This is a quick example. You should only open each web ONCE !
For example the dtDisctinctResults may contain 80 rows ( = 80 lists) but these 80 lists are on 4 sites. So you should only open SPWeb 4 times, not 80 times.
Since this has nothing to do with the question itselves, I leave this up to you.
To help you, I have quickly written a piece of code which would guide you in the right direction. I am not claiming this piece of code is written as it should be... http://pastie.org/3349098
This should work for you, more info on: http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spsitedataquery.lists.aspx
PS: It might be possible that you need to assign more properties of the query class. here is my working example for tasks which are not completed:
SPSiteDataQuery oQuery = new SPSiteDataQuery();
oQuery.Lists = "<Lists ServerTemplate='107' />";
oQuery.Query = "<Where><Neq><FieldRef Name='" + "Status" + "' /><Value Type='Text'>" + "Completed" + "</Value></Neq></Where>";
oQuery.Webs = "<Webs Scope='SiteCollection' />";
Above code will return all ListItems (which are not completed) in task lists