I know the answer (it's 42)

A blog on coding, .NET, .NET Compact Framework and life in general....

October, 2005

Posts
  • I know the answer (it's 42)

    C# : Enum and overriding ToString on it

    • 50 Comments

    I saw two posts on Enums today on Eric Lipperts and Chris Rathjen's blog. Enums are significantly different from the other types and people run into unusal problems while working with them.

    C++

    The CLI enum is considerably different from the native C++ enum and therefore you need to be careful how you define and use them in Managed C++. In new syntax (C++/CLI whidbey) the following code compiles even though both the enums define the same name Cool.

    enum class Coolness // class indicates this is a C++/CLI enum

    {

    NotSoCool,

    Cool,

    SuperCool

    };

    enum class TempRange

    {

    Cool,

    Hot,

    VeryHot,

    };

    In old syntax (pre whidbey) you need to define the enum as __value enum Coolness. In case you drop the class then you are using the native C++ enum and according to C++ specification the enumerator declarations are promoted to the same scope as the enumerated type declaration and the code will fail to compile pointing out a redefinition of Cool.

    C#

    In C# we do need not care about these as there is only one definition of enum which is that of the CLI enum.

    Common things like the first enum member get the value 0, the value of a subsequent member is calculated by adding 1 to the member textually preceeding it, you can assign values explicitely to a enum member are well-known. However there are some not so well known usages as well.

    enum Coolness : byte

    {

    NotSoCool = 5,

    Cool,

    VeryCool = NotSoCool + 7,

    SuperCool

    }

    Coolness coolType = Coolness.VeryCool;

    Console.WriteLine("Underlying type: {0}", Enum.GetUnderlyingType(coolType.GetType()));

    Console.WriteLine("Type Code : {0}", coolType.GetTypeCode());

    Console.WriteLine("Value : {0}", (byte)coolType);

    By default the compiler uses Int32 to store the enum members. Here we are asking it to use byte. VeryCool uses a reference to the NotSoCool and will get the value 12. So the out put of the code above will be

    Underlying type: System.Byte
    Type Code      : Byte
    Value          : 12

    Since all enums have System.Enum as the abstract base type, a lot of funcionality becomes available to get details about the enum type.

    If you want to print the value of the enum then it can be done in the following ways

    Console.WriteLine(coolType.ToString("G")); // name of the constant

    Console.WriteLine(coolType.ToString("F")); // name of the constant

    Console.WriteLine(coolType.ToString("X")); // value is hex

    Console.WriteLine(coolType.ToString("D")); // value in decimal

    Output:
    VeryCool VeryCool 0C 12

    F and G gives the same value in this case. They differ based on whether FlagsAttribute is applied to it.

    You can also get a array filled with either the value (GetValues) or names (GetNames) of all the constants in the enum.

    string[] names = Enum.GetNames(typeof(Coolness));

    int index = 0;

    foreach (Coolness coolVal in Enum.GetValues(typeof(Coolness)))

    {

    Console.WriteLine("{0,-10} => {1}", names[index++],

    coolVal.ToString("D"));

    }

    This prints

    NotSoCool  => 5
    Cool       => 6
    VeryCool   => 12
    SuperCool  => 13

    You can also query the name of the constant in the enum that has the specified value or whether a value is defined in the enum or not. The following will print cool and 5 is not defined.

    Console.WriteLine(Enum.GetName(typeof(Coolness), 6));

    if(!Enum.IsDefined(typeof(Coolness), (byte)7))

    Console.WriteLine("5 is Not Defined");

    Overriding ToString()

    You cannot override the ToString of the enum type. So in case you wanted to display "Not so cool" instead of NotSoCool when someone called ToString on your enum type then you cannot do that simply by overriding the ToString.

    This is a common issue that comes up frequently when you want to show values in reports, web pages, XML where you want to put in human readable text for enum values. Commonly people use non-generic solution of maintaining arrays of these descriptions and get text out of them by indexing using the enum value or some other things like storing it in a hashtable and using the ToString value as the key to get the desciption out.

    A generic solution would be to apply custom attributes on the enum constants and write static methods to get the desciption. See the modified code below

    using System;

    using System.Reflection;

    namespace FunWithEnum

    {

    enum Coolness : byte

    {

    [Description("Not so cool")]

    NotSoCool = 5,

    Cool, // since description same as ToString no attr are used

    [Description("Very cool")]

    VeryCool = NotSoCool + 7,

    [Description("Super cool")]

    SuperCool

    }

    class Description : Attribute

    {

    public string Text;

    public Description(string text)

    {

    Text = text;

    }

    }

    class Program

    {

    static string GetDescription(Enum en)

    {

    Type type = en.GetType();

    MemberInfo[] memInfo = type.GetMember(en.ToString());

    if (memInfo != null && memInfo.Length > 0)

    {

    object[] attrs = memInfo[0].GetCustomAttributes(typeof(Description),
    false
    );

    if (attrs != null && attrs.Length > 0)

    return ((Description)attrs[0]).Text;

    }

    return en.ToString();

    }

    static void Main(string[] args)

    {

    Coolness coolType1 = Coolness.Cool;

    Coolness coolType2 = Coolness.NotSoCool;

    Console.WriteLine(GetDescription(coolType1));

    Console.WriteLine(GetDescription(coolType2));

    }

    }

    }

    Using this approach is pretty generic because for all enum constants that have this attribute applied to it, the desciption will be picked up from it and for those that do not have the attribute the common ToString() method will be called to get the description. However, the GetDescription uses reflection and can be slow.

    The method shown above needs an explicit method call. If you prefer enum.GetDescription() then you need to use extension method as outlined here.

  • I know the answer (it's 42)

    Ruby: Webserver in 70 lines of code

    • 21 Comments

    <Updated the sources to add logging and default file index.html handling. Now the code is about 90 lines :(>

    I decided to write a http-server in Ruby on Windows to see how much code it requires as I have been reading about how Ruby gets your work done much easily and much faster. Some of the new things in C# 2.0 /3.0 have been already around in Ruby for some time and they make coding in Ruby fun and very interesting. I'll share my experiences about a some of the features in Ruby that I'd like to see in C#.

    This is a no-frills minimal implementation which any hacker can break in about 15 minutes :) So I deployed it over the intranet. I hosted my personal site from http://www.geocities.com/basuabhinaba on the server and it worked first time.  The code below should work without much modifications, just replace the IP address xxx.xxx.xxx.xxx to the one on your machine. I was amazed at how soon I was able to code this thing up in Ruby (doesn't say much about code quality though :) )

    Features

    1. Multi-threaded server
    2. Allows adding one base local folder from which pages are served. Request out side this folder would be refused (I hope it'll be refused)
    3. Supports common file formats like html, jpeg, gif, txt, css. I'll add more with time or I may just decide to use the Win32 API to read ContentType from the registry so that everything works
    4. Support for page not found

    Issues

    1. No security at all!!!! other than redumentary code to stop users from accessing files outside of the base folder
    2. No concept of default file (e.g. index.html) or directory listing in case request comes to access a folder
    3. There is some code in this that is windows specific
    4. No logging support for now

    Finally the Code

    It took me about 70 lines of code to get this to work.

    require 'socket'
    
    class HttpServer
      def initialize(session, request, basePath)
        @session = session
        @request = request
        @basePath = basePath
      end
    
      def getFullPath()
        fileName = nil
        if @request =~ /GET .* HTTP.*/
          fileName = @request.gsub(/GET /, '').gsub(/ HTTP.*/, '')
        end
        fileName = fileName.strip
        unless fileName == nil
          fileName = @basePath + fileName
          fileName = File.expand_path(fileName, @defaultPath)
          fileName.gsub!('/', '\\')
        end
        fileName << "\\index.html" if  File.directory?(fileName)
        return fileName
      end
    
      def serve()
        @fullPath = getFullPath()
        src = nil
        begin
          if File.exist?(@fullPath) and File.file?(@fullPath)
            if @fullPath.index(@basePath) == 0 #path should start with base path
              contentType = getContentType(@fullPath)
              @session.print "HTTP/1.1 200/OK\r\nServer: Makorsha\r\nContent-type: #{contentType}\r\n\r\n"
              src = File.open(@fullPath, "rb")
              while (not src.eof?)
                buffer = src.read(256)
                @session.write(buffer)
              end
              src.close
              src = nil
            else
              # should have sent a 403 Forbidden access but then the attacker knows that such a file exists
              @session.print "HTTP/1.1 404/Object Not Found\r\nServer: Makorsha\r\n\r\n"
            end
          else
            @session.print "HTTP/1.1 404/Object Not Found\r\nServer: Makorsha\r\n\r\n"
          end
        ensure
          src.close unless src == nil
          @session.close
        end
      end
    
      def getContentType(path)
        #TODO replace with access to HKEY_CLASSES_ROOT => "Content Type"
        ext = File.extname(path)
        return "text/html"  if ext == ".html" or ext == ".htm"
        return "text/plain" if ext == ".txt"
        return "text/css"   if ext == ".css"
        return "image/jpeg" if ext == ".jpeg" or ext == ".jpg"
        return "image/gif"  if ext == ".gif"
        return "image/bmp"  if ext == ".bmp"
        return "text/plain" if ext == ".rb"
        return "text/xml"   if ext == ".xml"
        return "text/xml"   if ext == ".xsl"
        return "text/html"
      end
    end
    
    def logger(message)
      logStr =  "\n\n======================================================\n#{message}"
      puts logStr
      $log.puts logStr unless $log == nil
    end
    
    basePath = "d:\\web"
    server = TCPServer.new('XXX.XXX.XXX.XXX', 9090)
    logfile = basePath + "\\log.txt"
    $log = File.open(logfile, "w+")
    
    loop do
      session = server.accept
      request = session.gets
      logStr =  "#{session.peeraddr[2]} (#{session.peeraddr[3]})\n"
      logStr += Time.now.localtime.strftime("%Y/%m/%d %H:%M:%S")
      logStr += "\n#{request}"
      logger(logStr)
    
      Thread.start(session, request) do |session, request|
        HttpServer.new(session, request, basePath).serve()
      end
    end
    log.close
    

     

  • I know the answer (it's 42)

    C#: try and retry

    • 17 Comments

    In many situation when something fails (exception is thrown) in the try block you want to retry that again. This could be a network timeout exception, or some other resource unavailability where you expect the same piece of try block code to succeed if you execute it again.

    How you do it in Ruby

    Let us assume there is some networkAccess() function which sometime throws a TimeoutException. In Ruby you can write code as follows.

    begin                  # try in C#
      networkAccess()
    rescue Exception => ex #same as catch (Exception ex) in c#
      retry
      puts "Finally quiting"
    end

    Here the retry keyword makes the preceeding try block (starting with begin in case of Ruby) to be executed again. This code can be further enhanced to create a custom Exception class which has a public attribute which is used to inform the caller whether it can call the failing routine again. In ruby this'd be

    class TimeoutException < Exception
      attr :okToRetry       # public attribute in C#
      def initialize(value) # constructor in c#
        @okToRetry = value
      end
    end
    // simulate a network access failure which succeeds on 3rd attempt
    

    def
    networkAccess() $val += 1 raise TimeoutException.new($val < 3) #throw new TimeoutException end $val = 0 begin networkAccess() rescue TimeoutException => ex #catch (TimeoutException ex) retry if ex.okToRetry puts "Finally quiting" end

    Here the failing callee function networkAccess raises (throws) an exception using a public attribute in the exception class to signal the caller to indicate if it can be called again.

    In C#

    In C# unfortunately (??) there is no support for retry. We can debate whether it'd be useful, but I feel it would make the exception handling more complete and expressive if it did. There are two workarounds. One is using goto :) and other is what we notmally use, by converting the exception to a return value and calling the failed routine again based on that.

    TryLabel:

    try

    {

    downloadMgr.DownLoadFile("file:///server/file", "c:\\file");

    Console.WriteLine("File successfully downloaded");

    }

    catch (NetworkException ex)

    {

    if (ex.OkToRetry)

    goto TryLabel;

    }

    If you compare this with the retry in Ruby the difference in the expressiveness is evident.

    The other options is to create a wrapper around this call and convert the exception to some return code and call that wrapper again based on whether its ok to call the failing function

    public static bool Wrapper(DownloadManager downloadMgr)

    {

    try

    {

    downloadMgr.DownLoadFile("file:///server/file", "c:\\file");

    return true;

    }

    catch (NetworkException ex)

    {

    Console.WriteLine("Failed to download file: {0}", ex.Message);

    return (!ex.OkToRetry);

    }

    }

    static void Main(string[] args)

    {

    while (!Wrapper(downloadMgr)) ;

    }

    Here the wrapper converts the failure in DownloadFile to false return code and the caller goes on calling wrapper as long as return code is false.

  • I know the answer (it's 42)

    C#: Anonymous methods are not closures

    • 26 Comments

    <Edit: See the extended discussion at the end of which I conclude Anonymous methods are indeed lexical closures!!! >

    Anonymous methods in C# are just anonymous methods and do not represent true lexical closure. There are a lot of samples and code out there explaining why. I use a simple example in my mind to remember why it is not the same.

    First lets see how the sample works in a language like Ruby which implements true lexical closure.

    $arr = Array.new

    # function funcGen fills the array arr with generated

    # functions (closures) that print an integer i. i varies

    # from 0 to val (10) when the function is generated

    def funcGen(val)

    0.upto(val) do |i| # same as for(i=0;i<val;i++)

    $arr[i] = Proc.new { # Proc.new creates the closure

    print i # body of the closure

    print ' '

    }

    end

    end

    funcGen(10) # call funcGen to fill the array
    # each function in the array arr is called to print

    # the value of i

    $arr.each do |val|

    val.call

    end

    Definition of closure requires that the lexical state of the closure when it's created is preserved. So all the variables (environment) used by the closure at the timeof  its creation should be captured at a point in time. Since Ruby implementes true closure and it does this the result of running the above code is

    0 1 2 3 4 5 6 7 8 9 10

    If we see the same sample in C# it'll be some thing like

    using System;

    namespace AnonymousMethod

    {

    delegate void Func();

    class Program

    {

    static Func[] funcArr = new Func[10];

    static void fillFunc(int count)

    {

    for (int i = 0; i < count; i++)

    {

    funcArr[i] = delegate()

    {

    Console.Write("{0} ", i);

    };

    }

    }

    static void Main(string[] args)

    {

    fillFunc(funcArr.Length);

    for (int i = 0; i < funcArr.Length; i++)

    {

    funcArr[i]();

    }

    }

    }

    }

    However, even though the same logic as in Ruby is implemented in this C# code the result is totally different and is

    10 10 10 10 10 10 10 10 10 10

    So in this case the value of i when the anonymous method was created is NOT used and the last modified value of i is used. This clearly indicates that lexical environment of all these methods are not closed. In anonymous methods these read-only variables are shared between the outer method and all the other anonymous mehtods. This sample can be tweaked a little to get it to match that of Ruby. The modified sample is as below with all changes marked in bold

    using System;

    namespace AnonymousMethod

    {

    delegate void Func();

    class Program

    {

    static Func[] funcArr = new Func[10];

    static void fillFunc(int count)

    {

    for (int i = 0; i < count; i++)

    {

    int j = i;

    funcArr[i] = delegate()

    {

    Console.Write("{0} ", j);

    };

    }

    }

    static void Main(string[] args)

    {

    fillFunc(funcArr.Length);

    for (int i = 0; i < funcArr.Length; i++)

    {

    funcArr[i]();

    }

    }

    }

    }

    With this change in code the output will get changed and will be the same as the Ruby program (0 1 2 3 4 5 6 7 8 9). The difference in the result further strengthens the fact that true closure is not implemented by C#. Inspection of the generated assembly with Reflector clearly shows why...

    In either case to encapsulate the anoymous method and the variable i it referes to the compiler generates a class

    [CompilerGenerated]

    private sealed class <>c__DisplayClass2

    {

    public <>c__DisplayClass2();

    public void <fillFunc>b__0()

    {

    Console.Write("{0} ", this.i);

    }

    public int i;

    }

    The method in bold is the anonymous method.

    In the first case while parsing the fillFunc method the compiler sees the following code

    for (int i = 0; i < count; i++)

    {

    funcArr[i] = delegate()

    {

    Console.Write("{0} ", i);

    };

    }

    and figures out that a variable i from the outer scope is used by the anonymous method and the compiler emits the following code

    private static void fillFunc(int count)

    {

    Func func1 = null;

    Program.<>c__DisplayClass2 class1 = new Program.<>c__DisplayClass2();

    class1.i = 0;

    while (class1.i < count)

    {

    if (func1 == null)

    {

    func1 = new Func(class1.<fillFunc>b__0);

    }

    Program.funcArr[class1.i] = func1;

    class1.i++;

    }

    }

    It is obvious from this code that only one object class1 of the generated class is created and is shared between all the anonymous methods and the loop generating the methods. So if anyone of the methods are called later, the last modified value of i (= 10) will be returned.

    For the second case on seeing

    static void fillFunc(int count)

    {

    for (int i = 0; i < count; i++)

    {

    int j = i;

    funcArr[i] = delegate()

    {

    Console.Write("{0} ", j);

    };

    }

    }

    The compiler generates the following code

    private static void fillFunc(int count)

    {

    for (int num1 = 0; num1 < count; num1++)

    {

    Program.<>c__DisplayClass1 class1 = new Program.<>c__DisplayClass1();

    class1.j = num1;

    Program.funcArr[num1] = new Func(class1.<fillFunc>b__0);

    }

    }

    Here the class used to encapsulate the anonymous method is very similiar to the one used in the first case. However, since the method uses a variable inside the loop, for each iteration a new object is created. This results is each anonymous methods having its own copy of the object and hence the value of j in it is same as it was at the time of the method creation.

  • I know the answer (it's 42)

    C#: Comparison operator overloading and spaceship operator

    • 15 Comments

    Lets consider I have a class Employee which has  Name and JobGrade fields. I want to overload the comparison operators for this class so that it can participate in all types of comparison including <. <=, ==, >=, != and Equals. I want to translate the comparison in-between two Employee objects to be a comparison between the JobGrade . Since I do not want to write the comparison logic each time, typically I'd implement the comparison in one method and from comparison operator overloading methods call this common method. So in C# I'd do something like.

    class Employee

    {

    public Employee(string name, int jobGrade){

    Name = name;

    JobGrade = jobGrade;

    }

    public string Name;

    public int JobGrade;

     

    public static bool operator <(Employee emp1, Employee emp2){

    return Comparison(emp1, emp2) < 0;

    }

    public static bool operator >(Employee emp1, Employee emp2){

    return Comparison(emp1, emp2) > 0;

    }

    public static bool operator ==(Employee emp1, Employee emp2){

    return Comparison(emp1, emp2) == 0;

    }

    public static bool operator !=(Employee emp1, Employee emp2){

    return Comparison(emp1, emp2) != 0;

    }

    public override bool Equals(object obj){

    if (!(obj is Employee)) return false;

    return this == (Employee)obj;

    }

    public static bool operator <=(Employee emp1, Employee emp2){

    return Comparison(emp1, emp2) <= 0;

    }

    public static bool operator >=(Employee emp1, Employee emp2){

    return Comparison(emp1, emp2) >= 0;

    }

    public static int Comparison(Employee emp1, Employee emp2){

    if (emp1.JobGrade < emp2.JobGrade)

    return -1;

    else if (emp1.JobGrade == emp2.JobGrade)

    return 0;

    else if (emp1.JobGrade > emp2.JobGrade)

    return 1;

    return 0;

    }

    }

    This is kind of huge as I have to overload each comparison operator individually even though what I want is to just make Employee object comparable to any other Employee object. What happens is as follows

    1. public static bool operator <=(Employee emp1, Employee emp2) gets compiled to a method named bool op_LessThanOrEqual(Employee, Employee). Similiar naming convention is used for the other operators.
    2. On seeing the code emp1 <= emp2 the compiler emits code to call the method op_LessThanOrEqual

    This makes overloading operators individually a requirement.

    What if

    In some languages like Ruby and also Perl (I am not that sure on perl) there is a concept of space ship operator <=>. This operator must return less than 0, equal to 0, greater than 0 based on whether the expression on the left is less than, equal-to or greater than that on the right (similiar to IComparable:CompareTo). If C# compiler supports the concept of the space-ship operator then we can simply overload this one operator and expect the compiler to emit code to call this operator for all comparison. So if C# supports this then the above code would look like

    class Employee

    {

    public Employee(string name, int jobGrade){

    Name = name;

    JobGrade = jobGrade;

    }

    public string Name;

    public int JobGrade;

     

    public override bool Equals(object obj){

    if (!(obj is Employee)) return false;

    return this == (Employee)obj;

    }

    // same in the lines of IComparable:CompareTo

    public static int operator <=>(Employee emp1, Employee emp2){

    if (emp1.JobGrade < emp2.JobGrade)

    return -1;

    else if (emp1.JobGrade == emp2.JobGrade)

    return 0;

    else if (emp1.JobGrade > emp2.JobGrade)

    return 1;

    return 0;

    }

    }

    In this case what'll happen is as follows

    1. public static int operator <=>(Employee emp1, Employee emp2) gets compiled to bool op_SpaceShip(Employee, Employee)
    2. On seeing emp1 <= emp2 the compiler emits code to call the method op_SpaceShip(emp1, emp2) <= 0
    3. On seeing emp1 != emp2 the compiler emits code to call the method op_SpaceShip(emp1, emp2) != 0
    4. Or generically emp1 op emp2 gets compiled to op_SpaceShip(emp1, emp2) op 0

    Interfaces like IComparable already exists which needs the class to implement CompareTo which works exactly like <=> operator overloaded as above. If only the compiler directly made calls to this then the need for one to implement this interface and then make calls to this method gets removed.

    The overloaded <=> acts as a filler. In case <= and => are already overloaded for a class then calls are made to these methods and for operators not overloaded like == and != calls are made to <=>.

    Its not important (atleast to me) how we achieve this and can include ways like have a method CompareTo in Object in the same lines of Equals and make the compiler emits calls to it based on the operator getting used or use explicite <=> operator overloading. Either way the need to overload all 5 operators should be eliminated.

  • I know the answer (it's 42)

    C#: structs and Interface

    • 18 Comments

    The fact that a struct can implement an interface is well known and so is the fact that casting a value type into an interface leads to boxing of the value type. This is because methods in interfaces are defined as virtual and to resolve virtual references, vtable (method table) look up is required. Since value types do not have pointers to vtable they are first boxed into a reference type and then the look up happens.

    This boxing leads to some performance penalty. See Rico Mariani's performance quiz for an example.

    The fact that such boxing takes place on casting to interfaces can lead to subtle issues in code. Consider the following

    interface IPromotion {

    void promote();

    }

    struct Employee : IPromotion {

    public string Name;

    public int JobGrade;

    public void promote() {

    JobGrade++;

    }

    public Employee(string name, int jobGrade) {

    this.Name = name;

    this.JobGrade = jobGrade;

    }

    public override string ToString() {

    return string.Format("{0} ({1})", Name, JobGrade);

    }

    }

    class Program

    {

    static void Main(string[] args)

    {

    Employee employee = new Employee("Cool Guy", 65);

    IPromotion p = employee;

    Console.WriteLine(employee);

    p.promote();

    Console.WriteLine(employee);

    }

    }

    Here the output would be
    Cool Guy (65)
    Cool Guy (65)

    So even after calling p.promote() the value of JobGrade in employee does not increase. The reason is that on implicitly casting employee to IPromotion p a temporary boxed object is created and p.promote updates the JobGrade in this temporary object and not on original employee value type. Since after this usage the temporary boxed object is not refered to, the update to it is lost and it is garbage collected.

    If however we change the code and make Employee a class the output would become as expected

    Cool Guy (65)
    Cool Guy (66)

    The reason being that now the boxing does not take place and the update happens on the original employee object.

  • I know the answer (it's 42)

    C#: String comparison guidelines and common usage

    • 2 Comments

    The recommendation for string comparison has been updated for Whidbey (Visual Studio 2005) and there is an excellent MSDN article on this. One of the highlights is the introduction of the clear cut enumeration that can be passed into most string comparison methods to indicate the kind of comparison you are trying to make.

    [Serializable]

    [ComVisible(true)]

    public enum StringComparison

    {

    CurrentCulture = 0,

    CurrentCultureIgnoreCase = 1,

    InvariantCulture = 2,

    InvariantCultureIgnoreCase = 3,

    Ordinal = 4,

    OrdinalIgnoreCase = 5,

    }

    The recommendation also states that for culture-agnostic comparisons use the Ordinal and OrdinalIgnoreCase comparisons. These are fast and also safe. They rely on byte matching and are excellent options for matching strings for internal (non-UI) processing.

    string.Compare(str1, str2, StringComparison.Ordinal);

    With the introduction of the guidelines, developers have become defensive and have started looking for all code that compare string and re-coding them to meet the guidelines. Let's take a look at the most common culture-agnostic string matching used in code and see if they are safe.

    string.Equals(string1, string2)

    Default interpretation for equals is Ordinal so using this is fine. In case of using any other type of comparison use in the lines of
    string.Equals(string1, string2, StringComparison.OrdinalIgnoreCase);

    string1 == string2

    In accordance to the class library design guidelines the == operator for string is overloaded and the implementation is same as for string.Equals. So this is equivalent of calling string.Equals(string1, string2, StringComparison.Ordinal) which is also fine.

    switch(string1)

    For small sized switch blocks of the form

    string myStr = "Abhinaba";

    // ...

    switch (myStr)

    {

    case "Abhinaba":

    Console.WriteLine("switch match"); break;

    default:

    Console.WriteLine("switch did not match"); break;

    }

    the code is compiled into 

    if ((myStr!= null) && (myStr == "Abhinaba"))

    {

    Console.WriteLine("switch match");

    }

    else

    {

    Console.WriteLine("switch did not match");

    }

    So this is also fine and the comparison will be a string.Equals( strA, strB, StringComparison.Ordinal) comparison.

    However, if the switch block is larger then things get complicated. A dictionary is created and lookup happens through Dictionary.TryGetValue with the string as the key. Lookup happens using code similar to

    int num1 = this.comparer.GetHashCode(key) & 0x7fffffff;

    for (int num2 = this.buckets[num1 % this.buckets.Length]; num2 >= 0; num2 = this.entries[num2].next)

    {

    if ((this.entries[num2].hashCode == num1) && this.comparer.Equals(this.entries[num2].key, key))

    {

    return num2;

    }

    }

    A quick look and a bit of poking around with reflector indicates that the result will ultimately be the same as string.Equals( strA, strB, StringComparison.Ordinal).

    InvariantCulture

    As the guideline suggests replace all InvariantCulture usage with either Ordinal or OrdinalIgnoreCase

    Be on the Safe Side

    The above discussion was mainly to figure out what to make out of common string comparison statements in existing code. Going forward I think its best to be defensive and clear in code and explicitly call the comparison methods and pass the correct StringComparison enumeration constant.

  • I know the answer (it's 42)

    C# 3.0 : using extension methods for enum ToString

    • 8 Comments

    In my previous blog I was trying to address the issue that when ToString is called on an enum the literal string for the enum constant is returned. Custom attributes can be used to tag localizable description string to the constants so that you can write functions that use reflection to get to the attribute and show that string. However this has a significant disadvantage as you need to write code as follows

    enum Coolness {

    [DescriptionAttribute("Not so cool")]

    NotSoCool = 5,

    [DescriptionAttribute("Very cool")]

    VeryCool = NotSoCool + 7,

    }

    class Program

    {

    static string GetDescription(Enum en)

    {

    // Uses reflection to get the attribute and returns it

    }

    static void Main(string[] args)

    {

    Coolness coolType = Coolness.VeryCool;

    Console.WriteLine(GetDescription(coolType));

    }

    }

    Calling GetDescription method on the enum is definitely not intuitive. This is why I had said that I love extension methods. Converting this to use C#3.0 extension method makes its intuitive and it'll be easy for the developer to remember that in the same lines as ToString there is also a ToDescription on enums.

    using System;

    using System.Reflection;

    using System.Collections.Generic;

    using System.Text;

    using System.Query;

    using System.Xml.XLinq;

    using System.Data.DLinq;

    using System.ComponentModel;

    // C# 3.0 syntax used...

    namespace FunWithEnum

    {

    enum Coolness

    {

    [DescriptionAttribute("Not so cool")]

    NotSoCool = 5,

    Cool, // since description same as ToString no attr are used

    [DescriptionAttribute("Very cool")]

    VeryCool = NotSoCool + 7,

    [DescriptionAttribute("Super cool")]

    SuperCool

    }

    static class ExtensionMethods

    {

    public static string ToDescription(this Enum en) //ext method

    {

    Type type = en.GetType();

    MemberInfo[] memInfo = type.GetMember(en.ToString());

    if (memInfo != null && memInfo.Length > 0)

    {

    object[] attrs = memInfo[0].GetCustomAttributes(
    typeof(DescriptionAttribute),

    false);

    if (attrs != null && attrs.Length > 0)

    return ((DescriptionAttribute)attrs[0]).Description;

    }

    return en.ToString();

    }

    }

    class Program

    {

    static void Main(string[] args)

    {

    Coolness coolType1 = Coolness.Cool;

    Coolness coolType2 = Coolness.NotSoCool;

    Console.WriteLine(coolType1.ToDescription());

    Console.WriteLine(coolType2.ToDescription());

    }

    }

    }

     

  • I know the answer (it's 42)

    C# : Where do you define an enum

    • 14 Comments

    Frequently while designing classes that have methods which accept enums as parameters, a common question arrises on where to define the enum. Whether to define it inside the class or in the same level as the class.

    Lets consider a class Folder which has a method List. It accepts a enum Filter and based on it prints the name of all files or directories in the Folder. We can define the enum at the same level as the Folder as below

    enum Filter

    {

    File,

    Dir

    }

    class Folder

    {

    public Folder(string path) { /* ... */ }

    public void List(Filter filter) { /* ... */ }

    }

    Folder folder = new Folder("c:\");

    folder.List(Filter.File);

    Or define it inside the Folder class as in

    class Folder

    {

    public enum Filter

    {

    File,

    Dir

    }

    public Folder(string path) { /* ... */ }

    public void List(Filter filter) { /* ... */ }

    }

     

    Folder folder = new Folder(@"c:\");

    folder.List(Folder.Filter.File);

    I think that the first approach is much simpler because otherwise you have to continually type in the complete scope of the enum as Folder.Filter . This soon becomes painfull. I first had a little difficulty understanding why do people still do this. Then I figured out that there are a lot of C++ programmers who have migrated to C# and in un-managed C++ the second approach is the way to go. Lets see why

    The issue with C++

    If we use the same code in C++ as in the first approach then we get the following

    /* 1 */ namespace MyNameSpace

    /* 2 */ {

    /* 3 */ enum Filter

    /* 4 */ {

    /* 5 */ File,

    /* 6 */ Dir

    /* 7 */ };

    /* 8 */

    /* 9 */ //char File[] = "c:\\foo\\bar";

    /* 10 */ class Folder

    /* 11 */ {

    /* 12 */ public:

    /* 13 */ Folder(char* path) { /* ... */ }

    /* 14 */ void List(Filter filter) { /* ... */ }

    /* 15 */ };

    /* 17 */ }

    According to C++ spec the enum constant File and Dir is raised to the same scope as that of Filter. So effectively nowhere in the whole namespace of MyNameSpace can variables of name File or Dir can be defined. So if you uncomment the 9th line then compilation will fail indicating redeclaration of variable File.

    So defining enums at the level of classes have serious consequence of namespace pollution. So C++ programmers generally put the enum declaration inside the class definition. This requires the client program to use scope resolution a bit too much even then this is worth the extra typing.

    However, in C# since this is a non-issue the enum must be declared at the same level as the class.

  • I know the answer (it's 42)

    C#: CIL supports overloading by return type

    • 9 Comments
    C# and most other languages that allow method overloading do not allow overloading by return type. What this means is that methods can be overloading only if they differ by parameters. So the following code will not compile as the methods differ only by return type

    class Employee

    {

    //...

    }

    class Program

    {

    static int Func(Employee emp) {

    return emp.Id;

    }

    static string Func(Employee emp) {

    return emp.Name;

    }

    }

    However, CIL does support overloading methods by return types, even though C#, VB does not . To implement convertion operator overloading C# compiler uses this feature (I know of one usage and I'm sure that there are more :) )

    Conversion Operator Overloading and return types

    In the following code we are overloading the conversion operator for Employee class so that the class can be easily converted (casted) to string or int.

    class Employee

    {

    public string Name;

    public int Id;

    public static explicit operator int (Employee emp) {

    return emp.Id;

    }

    public static explicit operator string (Employee emp) {

    return string.Format("{0} ({1})", emp.Name, emp.Id);

    }

    }

    Employee employee = new Employee("Abhinaba Basu", 23567);

    Console.WriteLine((int)employee);

    Console.WriteLine((string)employee);

    Inspection of the Employee class in the assembly with ILDasm or reflector reveals that there are two methods in it which are generated by the compiler.

    .method public hidebysig specialname static
    string op_Explicit(class ConversionOperator.Employee emp) cil managed

    .method public hidebysig specialname static
    int32 op_Explicit(class ConversionOperator.Employee emp) cil managed

    Both these methods are identical other than the return types (one returns a string the other an int). So CIL does support method overloading when the methods differ by return types.

     

  • I know the answer (it's 42)

    C#: Fun with #line directive

    • 5 Comments

    #line pre-processor directive, though not commonly used is very interesting. This directive makes the compiler report line numbers for source files differently. If you have the directive #line 1 on the 3nd line of a source file then the compiler will interpret the next line (4th) as the 1st line and will emit all error messages and any other kind of output messages based on this modified line numbering. You can also make the compiler report the source filename differently by giving the name of a file within quotes after the line number.

    If you try to compile the following piece of code

    /* 1 */ using System;

    /* 2 */

    #line 1 "coolFile.cs"

    /* 4 */ namespace LineDirective // treated as 1

    /* 5 */ { // treated as 2

    /* 6 */ class Program // treated as 3

    /* 7 */ { // treated as 4

    /* 8 */ static void Main(string[] args) // treated as 5

    /* 9 */ { // treated as 6

    /* 10 */ Invalid syntax; // treated as 7

    /* 11 */ throw new Exception("Bang");// treated as 8

    /* 12 */ }

    /* 13 */ }

    /* 14 */ }

    then even though the compilation failure happens for the junk string on the 10th line in the file program.cs the compiler will report failure on line 7 in the file coolFile.c

    Error 1 The type or namespace name 'Invalid' could not be found (are you missing a using directive or an assembly reference?) c:\MyStuff\Code\C#\LineDirective\LineDirective\coolFile.cs 7 13 LineDirective

    The compiler also stores this modified line numbering in the pdb and so if you comment out the junk string on the 10th line and build/run the program then an exception will be thrown on the 11th line. However you'll get the following in the console window.

    Unhandled Exception: System.Exception: Bang
    at LineDirective.Program.Main(String[] args) in C:\MyStuff\Code\C#\LineDirective\LineDirective\Program.cs:line 8

    Interestingly here the file name is the correct filename and not the one we had passed. I'm not too sure on whether this is as expected or is a bug. I'll try to find this out.

    Another interesting usage of #line directive is #line hidden. If you use this in a source file then all line information after this directive upto any other #line directive (other than another #line hidden) is skipped and not stored. Hence while stepping through code in the debugger these line will be skipped entirely.

    In the following code

    namespace LineDirective

    {

    class Program

    {

    static void Main(string[] args)

    {

    foo();

    }

    #line hidden

    static void foo()

    {

    Console.WriteLine("Bar");

    }

    #line default

    }

    }

    if you try to step into the function foo in the debugger you'll not be able to do so as the entire function definition is inside a #line hidden block and hence line number information for the whole function is missing in the pdb.

    How does this work?

    The .pdb file generated by the compiler contains line number information to allow the debugger to step through source code. In this for blocks of IL code the corresponding source file and line number information is stored. The #line directive makes the compiler change the line number information it puts into this file. There is an understanding between the debugger and the compiler that if the line number of a block of IL is set as 16707566 ( 0xFeeFee) then the debugger will simply step over this block of code. This is utilized in #line hidden and the compiler translates hidden to 0xFeeFee You can try out the following code to see this in action

    using System;

    namespace LinePreProcDirective

    {

    class Program

    {

    static void foo()

    {

    Console.WriteLine("foo");

    #line 16707566

    Console.WriteLine("bar");

    #line default

    }

    static void Main(string[] args)

    {

    foo();

    }

    }

    }

    The code marked in bold will be skipped over if you try to step through this code in the debugger.

  • I know the answer (it's 42)

    C#: How about borrowing some Ruby conditional expressions

    • 9 Comments

    After using Ruby for some time I have become quiet attached to its conditional statement syntax. In particular I like statement modifiers which allow you to tag conditional statements at the end of a normal statement.

    If C# supported this then in C# terms this'd mean instead of writing

    if (!File.Exist(fileName)) throw new FileNotExistException(fileName));

    You could have written

    throw new FileNotExistException(fileName)) if (!File.Exist(fileName));

    If things go as it seems this could actually be the future of C#.  I know this does not look that intuitive at first, but once I got used to it I started using it at all places. A quick glance in my Ruby sources reveals code like

    Utility.showHelp if ARGV.length < 2
    ARGV.each do |srcFileName|
        next if srcFileName =~ /^-/ #skip arguments starting with a -
        ...
    end
    

    I liked the unless keyword as well. This is a negated version of if used in Ruby. If C# supported this then we could have written

    unless (File.Exist(fileName)) throw new FileNotExistException(fileName)); 

    or better still

    throw new FileNotExistException(fileName) unless (File.Exist(fileName)); 

    What I felt was not that intuitive is that in Ruby if is not a statment but is an expression similar to the ?: conditional expression in C/C++/C#. So for conditional assignment of values in Ruby you can write code as in

    ageGroup = if age < 2
                 "Infant"
               elsif age < 19
                 "Teen"
               elsif age < 30
                 "Middle aged"
               else
                 "old"
               end 

    In C# this'd become

    string ageGroup;

    if (age < 2)

    ageGroup = "Infant";

    else if (age < 19)

    ageGroup = "Teen";

    else if (age < 30)

    ageGroup = "Middle aged";

    else

    ageGroup = "old";

  • I know the answer (it's 42)

    Secret unveiled : Why is the Whidbey release numbered 8.0.50727.42

    • 5 Comments

    The versioning scheme is 8.0.YMMDD.NN and that explains 8.0.50727. The mystery is with the build number .42. There are three top contenders for it, and no prize of guessing the correct one

    1. People were so impressed with my blog that they borrowed the number from my blog title
    2. Visual Studio 2005 is the answer to the universe. For people who have not read Douglas Adam's, The Hitch-Hikers Guide to the Galaxy, buy a copy and read it.
    3. When we come close to the ship date we freeze everything else other than the dot build number, which gets incremented each time a new build is churned out. Incidentally the forty second build was the good bits that got shipped.
  • I know the answer (it's 42)

    NonTech: Geekcity

    • 0 Comments

    Bangalore is famous world-over as the Indian version of Silicon city. I have never been to Silicon valley and so I'm not the right person to compare but a walk down some of the roads like the Airport road makes the comparison evident. Within a kilometer or two you'll see offices (or buildings) of Texas Instruments, Intel, ADI, IBM, Lucent, HP, Motorola, Microsoft, ADI on the side of the Road.

    What makes Bangalore special is that most people living in the city are not natives of the place and have recently (<5years) moved in. Most of them are young and work in the Hi-Tech industry. I have never been to a city with so low average age of people and where you hear people arguing over the merits of J2EE on the side of the road and pub fight over C# and Java (yes its true :) ). We had some friends who were hardcore MS technology fans and some other who worked in Sun Microsystem :)

    This unique environment along with institutes like IISc make Bangalore the geek city. Here are some reasons why

    • You get to see a newspaper vendor wearing a T-Shirts with "There are 10 types of people in the world: Those who understand binary and those who don't"
    • You get to see a House for sale poster that says "Make this your 127.0.0.1"
    • People say "that's our default" when referring to the pub they go to when they have no other place to go
    • Instead of saying "I do not want to go to that junk place" they say "I don't want to go to any foobar place"
    • Instead of saying "I have no choice" they say "I'll just use Select *"
    • Bikes have stickers on them that say "I play RoadRash"
    • Bike helmets commonly have "Intel inside" stickers on them. 
    • Some one got mad at me and shouted "I feel like Rebooting you"
    • You'll start believing that Wipro and Infosys manufactures bags and T-shirts because their names appear on all of them
  • I know the answer (it's 42)

    VS 2005 is out!!!!

    • 0 Comments

    The final word is out!!! This is a great time indeed for most developers out there, Visual Studio 2005 has been released!!!!

    I have been using Visual Studio for some time now, but all those years I was a customer of MS. This time I am in MS and in the DevTools team. Even though our product Visual Studio Team System is due next year I can hardly wait any longer. Its a proud moment for all of us here.

Page 1 of 1 (15 items)