I know the answer (it's 42)

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

December, 2005

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

    Watson, look up at the sky and tell me what you see

    • 4 Comments

    "Sherlock Holmes and Dr. Watson go on a camping trip, set up their tent, and fall asleep. Some hours later, Holmes wakes his faithful friend.
    "Watson, look up at the sky and tell me what you see."
    Watson replies, "I see millions of stars."
    "What does that tell you?" Holmes asked. Watson ponders for a minute.
    "Astronomically speaking, it tells me that there are millions of galaxies and potentially billions of planets. Astrologically, it tells me that Saturn is in Leo. Time wise, it appears to be approximately a quarter past three. Theologically, it's evident the Lord is all-powerful and we are small and insignificant. Meteorologically, it seems we will have a beautiful day tomorrow. What does it tell you?"
    Holmes is silent for a moment, then speaks. "Watson, you idiot, someone has stolen our tent."

    Error reporting dialogWhen I first saw the "We share your pain" spoof video, first thing that came to my mind was who created it!!! Obviously it was created by Microsoft!!! See at http://www.microsoft.com/uk/technet/itsshowtime/sessionh.aspx?videoid=9999. The spoof is on the error reporting dialog that pops up on application crashes. We call this the Watson dialog....

    Before I worked in Microsoft I saw this dialog come up couple of times. I thought with the huge user base that microsoft has does anyone really care? So I mostly ended up clicking on Don't Send. Right now the story is kind of the other-way around. I am in Microsoft and my application crashes actually throw up this dialog on users boxes!!!

    We are developing Visual Studio Team System which is a V1 product and hence there is limited audience outside of Microsoft. Mostly they are on Beta or CTP bits. So I was leading a happy life with all issues being reported with detailed logs and I'd mostly get repro-boxes where I could debug the failures.

    However, life changes fast and I got a couple of these Watson bugs as we call them. I then realized that these error reports are treated very seriously. There is a dedicated team that looks into all the error reports sent in and file bugs on the faulting products. To protect user's privacy and our strict data-collection policy  very limited data is gathered. However, the data is usually enough for us to locate the faulting code as we can get the stack trace and unhandled exception details.

    So next time you see one of these dialogs do send the error report. It'll surely be analyzed and will help us build better and more stable products... Read an excellect blog about this topic here

  • I know the answer (it's 42)

    snooping into TeamSystem activity logging

    • 9 Comments

    Brian Harry had blogged before on how we are using the activity logging on our Team System data-tier to actually measure load on our Team Foundation Server.

    How to enable logging

    TFSActivityLogging is a databsae created on the DT (data-tier) of TFS. To use it first you need to enable the logging. To do that locate the top level web.config file on the TFS. Its usually in some place like %ProgramFiles%\Microsoft Team Foundation 2005\Web Services\Web.config . Search for CommandLogging in the file and set it to something like Normal. After this you are set to go and all commands will be logged in the TFSActivityLogging database.

    How to see the log

    Open SQL Server Management Studio and run the simple SQL query select * from tbl_Command against this TFSActivityLogging database. You can also do this directly from the command prompt using T-SQL. Follow the steps below to do this

    • bring up a command prompt
    • run sqlcmd -S localhost -E
    • type select * from TFSActivityLogging.dbo.tbl_Command

    What you can do with it

    This log is used by us for various purpose including calculating load and also determining usage-pattern. If you have access to the DT you are next to God and you can also potentially snoop on other users. I'll take a simple example. Last time I had posted a Rss feed generator for Team Build. I just wanted to check if people are really using it. Since I know calls to my feed generator will result in calling the web-method GetListOfBuilds I ran the following command

    select * from tbl_Command where tbl_Command.Command = 'GetListOfBuilds'

    This gets me something like below

    4994 TFS Build GetListOfBuilds 0 2005-12-20 10:11:24.920 2015309 ArthurDent 65.52.52.129 Mozilla/4.0  NULL
    5001 TFS Build GetListOfBuilds 0 2005-12-20 10:13:24.213 892921 Trillian 65.52.52.129 Team Foundation (devenv.exe) NULL
    5016 TFS Build GetListOfBuilds 0 2005-12-20 10:20:39.750 498415 Slartibartfast 65.52.52.129 RssBandit/1.3.0.38 
    NULL
    5448 TFS Build GetListOfBuilds 0 2005-12-20 10:37:27.690 392972 Beeblebrox 65.52.52.113 RSSOwl/1.2 2005-11-06 NULL

    A look into this tells me that Slartibartfast and Beeblebrox did use Rss aggregator to get to the feed. ArthurDent used only web-UI (through a browser) and trillian only uses devenv to get the build details. I can even tell which aggregators are used by Slartibartfast (RssBandit) and Beeblebrox (RSSOwl) and they are in my good books for using my feed generator (you know who you are folks :) ).

  • I know the answer (it's 42)

    Team Build RSS Feed

    • 17 Comments

    <Update: After some complains that it is difficult to cut paste code out of the blog, I have zipped and placed the source here>
    <Update: Fixed so that you no longer need to copy the Microsoft.TeamFoundation.Build.Common.dll. Thanks to a Watson bug we got to this>

    A lot of programmers have the disease of trying to code everything for themselves. Sometime back I had a bout of the same disease.

    We wanted a tool which would notify the user when a Team Build is fired/completed. Having used bug-tracker tools before which polls bug databases and shows pop-up notifications I immediately got excited and wrote my own super-mutithreaded application called BuildTicker. It could do all the fancy things like track multiple Team Foundation Servers in different threads and show translucent pop-ups like Outlook 2003, had fancy owner-drawn UI. I even made the tool extendable so that I can plugin a bug-tracker for Team Foundation work-item tracking in future. All the while I kind of missed the point that all we need is a way to syndicate the information and rarely there is a way better than using existing technology and standards. JeffLu's source control RSS feed kind of got me to my senses. So here I am with a RSS feed for team build. This kind of retires the fancy BuildTicker I wrote before....

    How to use

    1. Unzip the sources into Team Foundation Server folder as in %Program Files%\Microsoft Team Foundation 2005\Web Services\Build\v1.0
    2. Add people whom you want to be able to see the feed in the Reader group for the team project.
    3. Use a feed reader like RSS Bandit which supports windows authentication. And for the feed url use http://<TFSServer>:<port>/Build/v1.0/rss.aspx?TeamProject=ProjectName replace the part marked in blue with your TFS and project name

    The Source

    <removed: Use the link to the source zip above >

    Note:

    This feed reader does not have the DOS attack blocker as in Jeff's feed reader....

  • I know the answer (it's 42)

    C#: Did if( a = b) lose its sting

    • 7 Comments

    One of the common typo of using if (a = b) in place of if (a == b) gave a lot of grief to programmers working in C and C++. If you make the typo, you have an expression that is always true if b is not 0 (mostly it isn't) and the compiler is not even polite enough to warn you. So many people taught themselves to use the inverted comparison as in

    int a = 1;

    if(a == 2)

    printf("Hello");

    if (2 == a) // inverted

    printf("Hello");

    People believed the inverted comparison was better because if you typed = instead of == you'd get a compilation error indicating that the "left operand of = must be a lvalue". I always thought that a person who remembers to type the inverted expression will anyway remember to not-type = in place of ==. I felt uneasy to see expressions this way.

    C# allows only boolean expression for comparison. This almost removed the chances of the typo to exist. You can make the same typo only if a is a boolean type. So the following code will fail to compile in C#

    int a = 1;

    if (a = 2)

    Console.WriteLine("Yea");

    Stating "Cannot implicitly convert type 'int' to 'bool'". So this virtually eliminates the chances of the typo leading to a bug. In case you do have something as below

    bool cond = false;

    bool othercond = true;

    if(cond = othercond)

    Console.WriteLine("Yea");

    it can potentially lead to a bug if you did not intend the =. As again there is no warning and one bug just sneaks in. Before this leads you to believe that a bug can sneak in only if the lvalue is boolean you need to carefully look at following

    class MyClass

    {

    public static implicit operator bool(MyClass mc)

    {

    return true;

    }

    }


    MyClass
    mc1 = new MyClass();

    MyClass mc2 = new MyClass();

    if (mc1 = mc2)

    Console.WriteLine("Yea again");

    This will compile without an warning because the class has an implicit cast to bool.  The compiler will not complain and you again have the same sneaky bug in your code.

  • I know the answer (it's 42)

    C#: Do we need checked exception in C#

    • 11 Comments

    We recently got hit by a bug where some method threw an exception which it was not supposed to. Since the thrown exception was not in the methods documented list of exception classes we did not have a catch for it and landed up with an unhandled exception crash. These kind of things are really bad when they originate from WinForm event handlers as there is no catch all block for every event and uncaught exceptions just terminate the form. 

    My instant reaction was this wouldn't have happened if we had checked exceptions  in C#. However, there has been a lot of debate on the inclusion of checked exception (as in Java) into C#. Ander's Hejlsberg has a great rational on this topic here. I think we need a good solution with this exception business, Java's solution is not good enough and C++ throw list is simply crap.

    Checked Exceptions as in Java

    <All Java code in this blog was written and tested with VJ# >

    Checked exceptions mean that every method is supposed to declare the various exceptions it can throw in the method's signature. The compiler then proceeds with static analysis to ensure that the method throws only those exceptions that it had declared or exceptions derived from them.

    public class A extends Exception

    {

    }

    public class B extends Exception

    {

    }

    public class C extends B

    {

    }

    public class Program

    {

    public static void func() throws B

    {

    throw new A(); // compilation failure

    throw new B(); // OK

    throw new C(); // OK as C extends B

    }

    }

    In the Java code above the compilation fails when we try to throw A as it does not derive from B. The compiler not only verifies that the method throws only the correct exceptions it also verifies that the caller handles all those exceptions. By "handle" the caller either needs to catch these exceptions or include them in its throws list.

    public class B extends Exception

    {

    }

    public class C extends B

    {

    }

    public static void func() throws B

    {

    throw new C();

    }

    For the above code you have two options of calling func

    public static void foo()

    {

    try {

    func();

    }

    catch (B b) {

    // ...

    }

    }

    or

    public static void foo() throws B

    {

    func();

    }

    In a micro sample like the one above checked exceptions looks super cool. So there is no need for documentation of list of exceptions. The compiler ensures that a method does not do anything sneaky and throw an exception it was not supposed to and it also ensures that you take care of all exceptions and do not become the author of a culprit method.

    However, in large real-life projects the whole idea starts breaking down. For an excellent discussion on this read Hejlsberg's comment

    C++ throw list (Exception specification)

    I cannot stop myself from stating that this is one of the most crappiest feature (??) in C++. First lets see how it works

    int foo() throw (B)

    {

    throw new A();

    }

    int bar() throw ()

    {

    throw new A();

    }

    as in Java you can give a list of exceptions that the class can throw. If the list is empty then the method is not supposed to throw any exception. The problem is that this is totally misleading to most programmers and makes them believe that this list is enforced as in Java. The truth is that it isn't. So the above code will compile just fine. The fact that foo is throwing A when its supposed to throw B and that bar is throwing A when its not supposed to throw any, is not checked by the compiler. This is more of exception specification (read fancy compiler supported documentation).

    What the compiler does is that when an exception is thrown which does not match the specification the global unexpected() handler is called at runtime. Since rarely you can do something intelligent in the global handler, you'd need to live with the terminate() call from there and watch in horror as your program dies miserably. The whole of this happens at run-time and there is no static check.

    So simply put the general guidelines is almost always "do not use exception specification". Sometimes however, the empty throw() is allowed as this can help the compiler optimize generated code as it need not take care of all the stack unwinding stuff. However, if you do get an exception in code you've marked with throw(), just pray and hope that the comp just does't burn itself down....

    Microsoft Visual C++ compiler does the right thing of just parsing and ignoring the throw list (exception specification). I think the time spent on implementing the C++ spec on this would've been waste of time and no-value would 've been added.

    C# and Spec#

    C# wisely (IMO) does not include checked exception. However, Spec# from Microsoft Research does implement this. Read about spec# implementation here. Spec# follows Java is its implementation and it used data-flow rules like the ones used in definite assignment to verify this.

    Since C# picks up a lot of things from Spec# (and COmega) I expected this to move into C#. Atleast for C#3.0 the announced plans do not include checked exceptions in C#....

  • I know the answer (it's 42)

    C#2.0: Nullable types, lifted operators and some compare weirdness

    • 1 Comments
    Recently I was stumped on some weird comparisons and I promised myself I'd do some investigations. I figured out with help of some people like Erric Lippert they are due to the inclusion of nullable types in the language. When a new feature is added the ripple effects reach every nook and corner of the language, nullable types are no exception to this. Consider the following code and try to guess whether they'll compile

    int i = 5;

    if ( i == null )

    Console.WriteLine ("null");

    if ( 5 == null )

    Console.WriteLine ("null");

    The answer is "NO" on C#1.1 but "YES, with warnings" on C#2.0. The warning give away the reason why they compile "The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type 'int?' ". The part in bold clearly indicates that the i and 5 are getting converted to the nullable type int?.

    Lifted conversion operator

    According to the C#2.0 spec if there exists an conversion from a type S to T then a lifted conversion operator exists from S? to T?. For this conversion T? will be unwrapped to T, then T will be converted to S and then S will be wrapped into a S?

    struct S

    {

    public static implicit operator S(T t){

    Console.WriteLine("Conversion T=>S");

    return new S();

    }

    }

    struct T

    {

    }

    class Program

    {

    static void Main(string[] args)

    {

    T t = new T();

    S s = t;

    T? tq = new T();

    S? sq = tq;

    }

    }

    In the above code even if T? to S? conversion does not exist directly it will go through. The output will have two "Conversion S=>T" indicating that even for the second conversion the same conversion operator was called. There is an exception rule to it though. Consider the following when applied to the same classes

    T? tq = null;
    S? sq = tq;

    For this the compilation will go through as ususual but the convertion function will not be called and sq will be null. This is called null propagating in which the null source is directly converted into null target without going through the underlying conversion function. However, the conversion function needs to exist so that the compiler can verify that the conversion is valid (even though it does not call it). In our conversion function we create a new S irrespective of the value of T. So if our function was called, sq would have been non-null which is not the case...

    Lifted Operators

    Lifted operators allow predefined and user-defined operators (overloaded-operators) that work for non-nullable types to be used for their nullable forms as well. Consider the code below

    struct S

    {

    public int val;

    public S(int val)
    {

    this.val = val;

    }

     

    public static S operator +(S s1, S s2)

    {

    Console.WriteLine("+ operator called");

    return new S(s1.val + s2.val);

    }

    }

    // user-defined operators

    S? sq1 = new S(5);

    S? sq2 = new S(6);

    S? resq = sq1 + sq2; // resq will be 11

    resq = sq1 + null; // resq will be null

     

    // pre-defined operators

    int i = 5;

    int? j = 6;

    int? k = j + i; // 11

    int? q = i + null; // null

    In the above code even though the + operator is overloaded for S it also works for S?. Even here null propagation takes place and for resq = sq1 + null; the overloaded operator function is not called as one of the sources is null.

    For the expression S? resq = sq1 + sq2; the code that is generated is something like

    S? resq = (sq1.HasValue && sq2.HasValue) ? (sq1.Value + sq2.Value) : (S?)null;

    Equality operator

    This is the one I hit in my previous blog. The == and != operators have been lifted so that it allows one operand to be a value of a nullable type and the other to be the null literal. So both of the following expressions are valid

    int i = 5;

    if (i == null)

    Console.WriteLine("null");

    if (5 == null)

    Console.WriteLine("null");

    However if you want to get the following to work you need overload the == and != (and Equals) of the type S

    S s = new S();

    // compile error is == and != is not overloaded

    if (s == null) Console.WriteLine("null");

  • I know the answer (it's 42)

    What do we work on here in Microsoft India

    • 0 Comments

    Frequently I have been asked the question, what kind of work is done in Microsoft India or MIDC? The number of questions grew with my recent post on BillG's visit to India and his announcements regarding the plans to grow MIDC and MS India in general.

    MIDC is the second MS R&D center outside of US. We work on a lot of stuff here. I am in DevTools group which has ownership of lot of interesting things. The list goes as

    1. Visual Studio Team System's Team Build component is developed here. I work in the dev-team for this product. Since this is a V1 product we get to work on a lot of cool stuff. The converter tools that help users to migrate from pre-existing tools like VSS, ClearQuest to TFS is also completely developed here
    2. Visual Studio for devices is also developed here
    3. One of the .NET languages VJ#.NET is completely owned in MIDC. A tool called JLCA which automatically converts existing Java code into C# is also owned by the team

    Other than my group there are a lot of other groups here too. This list includes....

    1. Some of the WinXP-SP2, Windows 2003 and Vista (Longhorn) features. Stuff like Fax, TAPI, Scanning, IE, Services for UNIX (SFU), Terminal Server, System Resource Manager, Remote access,
    2. Windows Serviceability group is located here. So if you have Windows 2000 and got a service pack update, you now know where it came from :-)
    3. Data Protection Manager
    4. Office in your pocket or Office for mobile devices is completely owned here.
    5. SQL Server 2005 Mobile Edition
    6. Mobile messaging client similar to MS Office Communicator 2005
    7. MS is developing a RFID (Radio Frequency Identification) infrastructure that is also completely owned here
    8. Some of the MSN stuff like connector for outlook, live-meeting, One-care...
    9. XBox is coming here. Not sure what exactly they'll be working on...

    The list is growing fast, check out http://www.microsoft.com/india/indiadev/ for more info on MIDC...

  • I know the answer (it's 42)

    C#: And I thought parallel assigment expressions were good

    • 7 Comments

    When I began using Ruby I loved most of the things I saw. I made couple (1 , 2 ) of posts on some of those features that I'd like to see in C#. When I started re-visiting code I wrote sometime back my views started to change considerably. One of these was the parallel assignment constructs in Ruby.

    At first it looks tempting and trivial. Let's see the classic example of swapping two variables. In C# you'd do something like

    string a = "Abhinaba";

    string b = "Basu";

    string temp = a;

    a = b;

    b = temp;

    This can be done beautifully using Ruby parallel assignment with just one line and no need for any temporary placeholder.

    a = "Abhinaba"
    b = "Basu"
    a, b = b, a

    Parallel assignment works by evaluating all expressions in the right-hand-side before any assignements are made. After that all assignments are made. So the effect is as if all assignments are made is parallel.

    x = 5
    a, x, c = x, 3, x+= 1

    In the code above the values after the assignment is a = 5, x = 3, c = 6. The expressions on the right are evaluated first, even though x is reset to 3 in the middle, it has no effect on the value assigned to c.

    The other simple rule is that if there are more lvalues than rvalues then the additional lvalues are made nil (as in C# null) and if there are more rvalues than lvalues then the additional rvalues are ignored. Till this point it's fine. I went around to all the folks I generally bug like Ankur with my usual dictum that these kinds of expressions are cool and C# should support them. Since in C# is strongly typed also has value-types, we can fail compilation when number or type of lvalue does not match the corresponding rvalues.

    But things in Ruby get complicated after this. This is specially true if the rvalue contains an array. See the following code snippets from Programming Ruby book

    a = [1, 2, 3, 4]  
    b,  c = a      # b == 1, c == 2 
    b, *c = a      # b == 1, c == [2, 3, 4] 
    b,  c = 99,  a # b == 99, c == [1, 2, 3, 4] 
    b, *c = 99,  a # b == 99, c == [[1, 2, 3, 4]] 
    b,  c = 99, *a # b == 99, c == 1 
    b, *c = 99, *a # b == 99, c == [1, 2, 3, 4] 
    

    So if the last lvalue is prefixed with an asterix as in *c then all the remaining values of the rvalues are converted to an array and assigned to c. Similarly if the last rvalue is an array and it is prefixed with an asterix as in *a, then it is expanded to its constituent values in place. If you think that this is getting complicated go figure out the following nested assignments

    b, (c, d), e = 1,2,3,4     # b == 1, c == 2, d == nil, e == 3 
    b, (c, d), e = [1,2,3,4]   # b == 1, c == 2, d == nil, e == 3 
    b, (c, d), e = 1,[2,3],4   # b == 1, c == 2, d == 3, e == 4 
    b, (c, d), e = 1,[2,3,4],5 # b == 1, c == 2, d == 3, e == 5 
    b, (c,*d), e = 1,[2,3,4],5 # b == 1, c == 2, d == [3, 4], e == 5 

    I did the unfortunate thing of using a complicated nested assignment in some code I wrote for incremental backup of my digital pictures. When I had to fix a bug in that code I had to go through the whole damn spec again!!!

  • I know the answer (it's 42)

    The programmer's disease of doing it yourself

    • 10 Comments

    I had been taking a lot of digital pictures over the last few months, especially of my daughter. The numbers had grown so much that managing them was getting out of hand, so I did what most programers would do. I wrote code to do the backup. I used Ruby for the project and at the end I was the proud owner of a command line utility that backs up all pictures taken after a specific date and I then burn them onto CDs. After I wrote the program one of the things that bugged me is why did I do this? There are already tons of programs out there which do the same and I'm sure does a better job of it. Many of them are free as well, so price is not an issue. Over the last year I wrote a lot of major stuff which I could have done without. The list goes like WinForm custom-controls, web-cam motion detectors, ruby web server, C++ web server, text web-browser (similar to lynx), chat client/server, shell-extensions, lot of console utilities, game of tic-tac-toe, screen-saver framework, Rss aggregator/generators, source line count utility and the list goes on.

    I have seen other coders have this similar do-it yourself trait where they write redundant stuff to take care of their day-to-day requirements or just for fun. But the question is why they do it. I think the reasons are varied and may include

    1. I think I can do a better job
    2. All tools out there sucks (mine doesn't)
    3. I feel macho when I can write a web-server (hehe I am going to give Apache and IIS run for there money)
    4. Plain paranoia, I cannot live without knowing how motion-detection works and the fact that the author of that sample knows it. Does he think he knows more then me?
    5. The fun when you get it done and the thing actually works!!!

    But seriously, I think this do it yourself teaches you a lot. And when one experiments with existing things new ideas come up and innovation takes place. So onto my next redundant project...

  • I know the answer (it's 42)

    C# 2.0: Generics, default(T) and compare to null weirdness

    • 25 Comments

    <Added additional stuff after a discussion on internal CSharp user list>

    I was going through the generics spec in C#2.0 and found something really weird.

    default(t)

    Consider the following code.

    class MyGenClass<T>

    {

    public void Method(ref T t)

    {

    t = null;

    }

    }

    This will not compile because because T may be a value type as well and there is no implicit conversion of null to a value-type. So to handle such situation where you want to reset a type in a generic class the default-value expression was instroduced.

    class MyGenClass<T>

    {

    public void Method(T t)

    {

    t = default(T);

    }

    }

    If the type in default-value expression at run-time evaluates to be a reference type then it'll return null, if its a value-type then it will return the value-types default value (essentially new T() which boils down to re-setting all bits to 0).

    null comparison weirdness

    Peculiarly though, you are allowed to compare t with null.

    class MyGenClass<T>

    {

    public void Method(T t)

    {

    if (t == null)

    Console.WriteLine("null");

    // do some processing*/

    }

    }

    I got a bit confused here, as I always thought that you cannot compare value-types to null. Then I tried the following code.

    int i = 5;

    if (i == null)

    Console.WriteLine("null");

    and it compiled fine, with a warning that i == null will always be false. But the weird thing is that it compiled and I just cannot figure out why does the compiler allow comparing a value type with null. However, I accepted it and thought I figured out that since value-type can be compared to null it explains why in the generic class I was able to compare t to null. Things got even weirder when I tried to put a value-type constraint on the generic class

    class MyGenClass<T> where T: struct

    {

    public void Method(T t)

    {

    if (t == null)

    Console.WriteLine("null");

    // do some processing*/

    }

    }

    Compilation failed, with the statement that == operator cannot be applied to T. Since compiler cannot validate that == operator is overloaded on T it fails. But what I cannot figure out is that even in the case where there were no constrains the compiler in no way can validate the same thing, then why did it allow the comparison with null.

    Time to send an email to internal CSharp alias to figureout whats going on....


    I did finally send the email to CSharp usergroup and after some discussions this is what came out.

    The comparison of the form int a = 5; if (a==null) was invalid in VS 2003, but this has changed with nullable types. The int gets converted to a nullable type and the lifted operator bool operator ==(int? x, int? y); is used (see 2.0 spec 24.3.1) .

    This answers why null comparison works in value types like int. Why null comparison is allowed in generic classes has a more involved reasoning. First of all there is an explicit rule in the spec which goes as

    There are special rules for determining when a reference type equality operator is applicable. For an equality-expression with operands of type A and B, […] if B is the null type, […] A is a type parameter and at runtime, the type parameter is a value type, the result of the comparison is false.

    This rule makes the comparison valid. However, I was not convinced about the reasoning behind the rule. Special cases like this break the flow and intuition one develops in a language. Moreover, it the above rule is valid then I'd argue the following code should also be valid

    class MyGenClass<T> where T: struct

    {

    public void Method(T t)

    {

    if (t == null)

    Console.WriteLine("null");

    // do some processing*/

    }

    }

    Here for the comparison t == null, T should have been auto-converted to its nullable counterpart T? and the comparison should have gone through (evaluated to false). I think the fact that a generic class with no constraint allows an expression and a generic class with additional constraint do not allow the same is un-intuitive.

     

  • I know the answer (it's 42)

    Bill Gates is in India and he's all over the place

    • 3 Comments

    I opened the morning newspaper and there he was on the top-page almost taking 25% of it. I opened the TV and he's there in the news rolling out grand plans for the future of Indian SW industry. Bill Gates is especially dear to Hyderbaadis. When all SW/HW giants were opening shops in Bangalore, Bill Gates and Microsoft chose Hyderabad. That was just the beginning. Yesterday he announced we are going to increase in size to about 7000 people (from 4000) with a investment of 1.7Bn over the next couple of years. Open retail chains in 33 cities selling SW, Games, Mice, Kbds and gaming devices. I am already feeling the euphoria!!!

    Couple of days back Soma announced we are moving into Xbox development here in MS India Development Center with about 15 developers and that'll grow with time. I am almost shivering at the thought of joining that team and getting to play Halo all day on the pretext of work. Oops I hope my boss does not read this :)

    The last couple of days has been special for India. Cisco announced a 1.1Bn investment, Vodafone invested another 1.5Bn. Intel also announced investment somewhere near 1Bn. The most important piece of news was that for the first time a group of NRIs (non-resident Indians) are planning to open a Semiconductor-chip manufacturing unit with the help of AMD. This alone asks for a investment of 3Bn dollar. Rumors were afloat for a long time that Intel, or Texas Instruments (where I worked before) would do this but years have gone by without any thing materializing....

  • I know the answer (it's 42)

    C#: some corner cases

    • 3 Comments

    I was just reading the blog entry corner cases in C# and Java when I remember two of such corner cases I hit

    Multi-line comments

    I was working on a tool to count source lines. In that I printed out number of uncommented lines as well. While working on it I commented out a block of code (I hate commented lines of code in production sources [:)] ) and was surprised at the result

    /*

    string startDelin = "/*"

    string endDelim = "*/";

    string oneLine = "//";

    ...

    */

    Its apparent from the source coloring that the */ inside the string endDelim was considered as the comment block end-delimiter. I thought it was a bug in the begining, however a look into the lexical grammer in the C# 1.2 spec Section 2.3.2 clarified that this is indeed the expected behavior.....

    Pre-processor directive

    This one is real corner case. I don't remember where I first saw this, but it goes as follows. There was a block of conditional code as in

    #if FOO

    /*

    #else

    /* some comment */

    class MyClass { }

    #endif

    The /* was lying around in a big block of code that was never used as FOO was never defined. When the same source got compiled with FOO defined,  still in the code the class MyClass could be found even though it's inside the #else block. The reason is as follows

    #define FOO

     

    namespace WeirdPreProcessing

    {

    #if FOO

    /*

    #else

    /* some comment */

    class MyClass { }

    #endif

    So defining FOO made the #else commented out and hence everything inside the #else block became a part of the #if block!!!

     

  • I know the answer (it's 42)

    C#: if sealed is supported then why not singleton

    • 13 Comments

    As I had said in my previous blog "Usefulness of a new feature is best understood if you try to implement something that the feature targets without using that feature". Lets take the example of the sealed class modifier. A sealed class cannot be inherited. The following code fails to compile with the error "cannot derive from sealed type Sealed.MyClass"

    sealed class MyClass

    {

    public string name = "Abhinaba";

    }

    class AnotherClass : MyClass // compilation failure

    {

    }

    The whole functionality of making a class non-inheritable comes from a single keyword sealed. This is what I love about C#. The language-designers took the care of incorporating common design patterns into the language. In C++ these simple things are missing. See what the Stroustrup has to say about it here. In C++ to get the same effect as in sealed C# class we need to do the following

    // forward declaration

    class NotInheritable;

     

    // This is the lock

    struct Prot

    {

    private: // This does the trick

    Prot(){};

    Prot(const Prot& p){};

    // The class that you want to lock

    friend class NotInheritable;

    };

    // Inherit from the lock (have to use virtual) and

    // This class will become un-inheritable :)

    class NotInheritable : virtual public Prot

    {

    public:

    NotInheritable()

    {

    cout << "Can create object" << endl;

    }

    };

    // Try the impossible and you will fail

    class TryToInherit : public NotInheritable

    {

    public:

    TryToInherit()

    {

    cout << "Successful in inheriting from TryToInherit" << endl;

    }

    };

     

    The trick here is to inherit your class from another class which has the constructor as private. This whole lot of work gets done easily using the sealed keyword in C#.

    Singleton

    When I saw the sealed keyword in C# one of the first things that occured to me is why singleton in not similiarly supported in C#. The singleton design pattern restricts the instantiation of a class to one object. In some cases the definition of singleton has got extended and is defined as just restricting the number of instances of a class. So the former definition is a special case (where the number is 1) of the extended definition.

    In C# one way to create singleton classes is as follows

    using System;

    public class Singleton

    {

    private static Singleton instance;

    private Singleton() { }

    public static Singleton Instance

    {

    get {

    if (instance == null) {

    instance = new Singleton();

    }

    return instance;

    }

    }

    }

    The advantage of this implementation is that this is true lazy instantiation as the instance is created only when asked for. However, this is NOT at all thread safe. If more than one thread try to create the object and enter the Instance accessor then due to a race-condition both may evaluate instance == null to true and create more than one objects.

    Other than using the lock and the double-check-locking I prefer to use the static instantiation which is not so lazy but is thread-safe in C#. This goes as follows

    public class Singleton

    {

    private static readonly Singleton instance = new Singleton();

     

    // makes the class NOT marked with beforeFieldInit 

    static Singleton() { }


    Singleton() { }

    public static Singleton Instance

    {

    get { return instance; }

    }

    }

    This is thread-safe as it is garaunteed that the static ctor will be executed only once per AppDomain. Its not lazy because if you have any other static fields then an access to it will trigger the creation of the instance. Even though coding up singleton is easy, it would enhance readability and also save some typing (and same some people from CTS) is the following was equally supported in C#

    public singleton class MyClass

    {

    // ...

    }

    Either the compiler could emit code in the same pattern or internally ensure that only one instance is created using something like reference counting.

  • I know the answer (it's 42)

    Developers are Super-hero

    • 6 Comments

    Bill Gates is coming to India for the launch of Visual Studio 2005, SQL Server 2005 and Biztalk. To celebrate this the rock band Parikrama has come out with a song about us (developers). Download the mp3 and lyrics from the Microsoft India site.

    I had never heard the band before but the song is real good. If you are not from India you should listen to it, as you'd get to hear some rock-band from here....

  • I know the answer (it's 42)

    C# 2.0: life was a bit more difficult without Static classes

    • 2 Comments

    Usefulness of a new feature is best understood if you try to implement something that the feature targets without using that feature. I started programming in C# when v2.0 was already available internally, so I got used to many of the new features in v2.0 without realizing the people outside have to work hard to get the same thing done.... One of these features is static classes. We use this in lot of places in our Team System code to group resources like constant strings, methods that operate on them and also utility methods that do not need any instance to operate. So a typical implementation is something like

    public static class BuildStatus

    {

    public static string Initializing { get { return BTRes.Initializing; } }

    public static string Sync { get { return BTRes.sync; } }

    public static string SyncCompleted { get { return BTRes.syncCompleted; } }

    /* ... */

    internal static bool IsOneOfCompletedStatus(BuildStatusIconID status)

    { /* ... */ }

    }

    Marking these classes as static ensure all of the following

    • Ensure that only static members can be placed in them
    • Unnecessary instance of the class will not be created
    • They are sealed and cannot be inherited from
    • They will not contain instance constructors

    Pre C#2.0 classes couldn't be marked as static and the workaround was to use the following pattern

    public sealed class MyStaticClass

    {

    private MyStaticClass(){}

    public static void MyStaticMethod(){ /* ... */}

    public static string Author = "Abhinaba";

    }

    So the class had to be marked sealed to stop inheriting and you needed to have a private constructor to stop creation of instances. Even then things did not work out perfectly as anyone could just go ahead and add instance members. With static modifier being supported for classes, the compiler can ensure that no instance members are added by mistake and it also helps in code-readability.

Page 1 of 1 (15 items)