tene en cuenta el codigo:
int primerValor = 2;
int segundoValor = primerValor;
primerValor = 3;
/* en este punto segundoValor no tiene el valor de 3, sino que conserva el valor de 2, puesto que en la asignacion "segundoValor = primerValor" no se le copio la referencia a "primerValor" sino que se copio el objecto entero. esto es debido a que "int" es un "value types" y no un "reference types" como lo es "System.Object" por ejemplo.*
ademas tene en cuenta que antes del foreach imprimis las variables "contX" y desp imprimis lo q tiene el dictionary.
si queres usar el dictionarytendrias que hacer dic[key]++ por ejemplo
saludos.daniel
no me deja pegar links pero pone en el google "value types msdn" que la primera entrada explica ese efecto que experimentas