How to check for duplicates in a List at compile time


have a list for windows performance counters, static , cannot changed @ run-time. however, on time list has grown large extremely tedious detect duplicates manually. have written tool can run checking duplicates still possible people may forget run tool or not aware of it.

figure out if there way detect duplicates @ compile time itself. code looks this:

public enum sampleenum  {      [description("sample")]      sample,  }

, class define performance counter:

public class perfcounter  {      public int countertype { get; set; }      public string countername { get; set; }  }

these 2 classes used follows:

public static class perfcountermanager  {      public static list<perfcounter> getcounters()       {          return new list<perfcounter>           {              new perfcounter              {                  countertypeid = (int) sampleenum.sample1,                  countername = getenumdescription(countertype.sample1)              },              new perfcounter              {                  countertypeid = (int) sampleenum.sample2,                  countername = getenumdescription(countertype.sample2)              },          }      }  }

function getcounters() may called many times, not modified except during compilation.

error can thrown not because countertypeid can duplicates, becausecountername which description of enum can duplicate. , because list large, not possible detect error while adding elements list. useful if can detected @ compile time itself.

i can't let go without giving comment should unit test.

if people forgetting run unit test, build process not robust enough.  in other words, should have automated build runs tool. make current tool post build step in solution if nothing else.

you create code contract , enable static checking, doing tantamount unit test.

even if wrote roslyn script validate it, still tantamount unit test.

the compiler checks checks.  it can find duplicate symbol names, duplicate switch cases, , stuff that.  but doesn't robustly detect similar objects or sophisticated compile-time assertions.  and think rewriting switch statement doesn't want.

i think robust way make sure code stays date give simplest declarations of what's going on.  the lightest syntax can imagine attribute enumerations -- , make use of reflection in implementation of getcounters.  have obtain attributed countertype each enum.

you can have static constructor validates once @ runtime using reflection , pukes if there's duplication or omission people aren't using project "forgot" validate.

and finally, use fxcop enforce enums have countertype attribute applied them.  but again, fxcop falls same category unit test, if ask me.

here's example:

using system; using system.collections.generic; using system.componentmodel;  //---------------------------------------------------------- // stuff seems pretty easy maintain me. enum sampleenum {     [countertype( countertype.a )] one,     [countertype( countertype.b )] two,     [countertype( countertype.c )] 3 }  enum countertype {     [descriptionattribute( "alpha" )] a,     [descriptionattribute( "bravo" )] b,     [descriptionattribute( "charlie" )] c }  //----------------------------------------------------------- // rest of stuff can put in place once.  [attributeusage( attributetargets.field, allowmultiple = false )] class countertypeattribute : attribute {     internal countertype countertype;     internal countertypeattribute( countertype t )     {         countertype = t;     } }   static class enumhelper {     public static t getattributeoftype<t>( enum enumval ) t : system.attribute     {         var attributes = enumval.gettype().getmember( enumval.tostring() )[0].getcustomattributes( typeof( t ), false );         return (t)attributes[0];     } }  class perfcounter {     public int countertypeid;     public string countername; }  class program {     static ienumerable<perfcounter> getcounters()     {         foreach( sampleenum v in enum.getvalues( typeof( sampleenum ) ) )         {             countertypeattribute attr = v.getattributeoftype<countertypeattribute>();             yield return new perfcounter()             {                 countertypeid = (int)v,                 countername = getenumdescription( attr.countertype )             };         }     }      static string getenumdescription( countertype countertype )     {         return countertype.getattributeoftype<descriptionattribute>().description;     }      static void main( string[] args )     {         foreach( var item in getcounters() )         {             console.writeline( "{0} : {1}", item.countertypeid, item.countername );         }     } } 



Visual Studio Languages  ,  .NET Framework  >  Visual C#



Comments

Popular posts from this blog

Azure DocumentDB Owner resource does not exist

job syspolicy_purge_history job fail in sqlserver 2008

Trying to register with public marketplace error with 'Get-AzureStackStampInformation'