EDIT: this works only if the string does not special UNICODE values as mjolka mentioned, char can be 16-bits in C#. It depends what you want to optimise, one way to optimise is to use the fact that a char is a value between 0 and 255. Therefore you could initialise directly an array of 255 at 0 values and use it to count each occurrences of each character. On the pro side, it is much faster, on the con side it uses a static array of 255 `int`. Also in C#, if you follow the guidelines of Resharper or StyleCop, they will recommend you to use var when you can and to not use '_' prefixing: public static int GetMaximumOccurence(string str) { var array = new int[255]; int maxcount = 0; foreach (char c in str) maxcount = Math.Max(maxcount, ++array[c]); return maxcount; } Finally this could be converted in a LINQ expression, which does the same thing: public static int GetMaximumOccurence(string str) { var array = new int[255]; return str.Select(c => ++array[c]).Concat(new[] {0}).Max(); } If you apply dss539 suggestion, it becomes: public static int GetMaximumOccurence(string str) { if (str.Length == 0) return 0; var array = new int[255]; return str.Select(c => ++array[c]).Max(); } If your string contains UNICODE characters, you will have to revert to a dictionary approach or use dss539 solution or increase the array size to be able to contain 2^16 values to make itwork in every case. Please note that 2^16 int start to be a significant amount of memory for just counting references ... A Dictionary approach would be: public static int GetMaximumOccurence(string str) { var countPerChar = new Dictionary<char, int>(); int maxcount = 0; foreach (char c in str) { int newVal; if (!countPerChar.ContainsKey(c)) newVal = (countPerChar[c] = 1); else newVal = (countPerChar[c] += 1); maxcount = Math.Max(maxcount, newVal); } return maxcount; } But I find dss539 answer is superior in the light of knowing that char is 16bit in C#.