So I thought I would share some code I wrote today, to help me formulate a design guideline. I'm trying to define what we should do for 'min' and 'max' as a rule for design guidelines: should it be Min and Max? Or Minimum and Maximum?

The first question of course is: what does the framework do today? That is, do we prefer MaxValue, or MaximumValue? And MinSize, or MinimumSize? So, I wrote up some standard reflection code to look at our own libraries and see what our existing libraries tell me. If you haven't tried Reflection before, I encourage you to do so: I always have a great fun time writing code that analyzes a library (some people are just weird I guess). Note that I only looked at public methods (the BindingFlags option below) becuase even while private members are well-formed, design guidelines typically don't apply to them. I am interested in both static and instance members of course.

Feel free to try this code out and see the results for yourself: I'm still trying to determine what the guideline should be. You can also use the basic principla to quickly discover what your own patterns are and decide if you're being consistent ;-).

using System;
using System.Collections;
using System.IO;
using System.Reflection;

class Test {
  static string max = "Max";
  static string min = "Min";
  static string maximum = "Maximum";
  static string minimum = "Minimum";

  public static void Main() {
    // so I'm looking at Everett assemblies: but pick your poison
    string[] files = Directory.GetFiles(@"C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322", "*.dll");

    ArrayList maxTypes = new ArrayList();
    ArrayList maximumTypes = new ArrayList();

    foreach (string file in files) {
      Console.Write("Processing {0}", Path.GetFileName(file));
      // some of the dll's aren't managed, so I simply ignore them:
      // but remember, catching all exceptions is NOT an encouraed practice
      try {
        Assembly a = Assembly.LoadFile(file);

        Type[] types = a.GetTypes();

        foreach(Type type in types) {
          MemberInfo[] members =
          type.GetMembers(BindingFlags.Instance | BindingFlags.Static |
                  BindingFlags.Public);

          foreach(MemberInfo mi in members) {
            // basic string formattig for nice display, always fun
            string name = String.Format("{0,-40}{1,-35}{2}",
                    type.Namespace, type.Name, mi.Name);

            // just decide which list to add the issues to
            if (mi.Name.StartsWith(maximum) || mi.Name.StartsWith(minimum)) {
              if (maximumTypes.IndexOf(name) < 0) {
                maximumTypes.Add(name);
              }
            } else if (mi.Name.StartsWith(max) || mi.Name.StartsWith(min)) {
              if (mi.Name.Length == 3 || Char.IsUpper(mi.Name[3])) {
                if (maxTypes.IndexOf(name) < 0) {
                  maxTypes.Add(name);
                }
              }
            }
          }
        }
      } catch {
        //you could do something more fancy here if you wanted
        Console.Write(" ...   error!!!");
      }
      Console.WriteLine();
    }

    // write the lists to two files,
    // one being all the short forms, one being the long forms
    WriteAllLines("maxTypes.txt", maxTypes, max, min);
    WriteAllLines("maximumTypes.txt", maximumTypes, maximum, minimum);
  }

  static void WriteAllLines(string file, ArrayList entries, string m1, string m2) {

    int dupeVals = 0;

    // Many types contain a Max AND a Min: From an accounting perspective
    // I chose to ignore this, so I get rid of dupes
    // I methodized the code here since I wanted to go through the list in
    // both directions. I'm not panicking over perf here, clearly!
    dupeVals += GetDuplicatedValues(entries, m1, m2);
    dupeVals += GetDuplicatedValues(entries, m2, m1);

    using (StreamWriter sw = new StreamWriter(file)) {
      sw.WriteLine("Total Entries in this list = {0}", entries.Count);
      sw.WriteLine("Duplicated Entries in this list = {0}", dupeVals);
      sw.WriteLine("Total Unique Values in this list = {0}", entries.Count - dupeVals);
      sw.WriteLine("--------------------------------");

      // check out V2.0, it makes this WAY easier: File.WriteAllLines
      foreach (string s in entries) {
          sw.WriteLine(s);
      }
      sw.WriteLine("--------------------------------");
    }
  }

  // this code is to basically ignore
  static int GetDuplicatedValues(ArrayList entries, string m1, string m2) {
    int dupeVals = 0;

    for(int i=0;i<entries.Count;i++) {
      string s1 = (string)entries[i];
      int found = s1.IndexOf(m1);

      if (found >= 0) {
        for(int j=i+1;j<entries.Count;j++) {
          string s2 = (string)entries[j];
          if ((s1.Length == s2.Length) && (found + m1.Length <= s1.Length)) {
            if (s1.Substring(0,found) == s2.Substring(0,found) &&
                  (s1.Substring(found + m1.Length) ==
                  s2.Substring(found + m1.Length)) &&
                  s2.Substring(found, m1.Length) == m2) {
              dupeVals++;
            }
          }
        }
      }
    }
    return dupeVals;
  }
}