Wednesday, May 14, 2008

4 nasty C# 3.5 code "changes" for your last day at work

I recently left my job of over 8 years, and it got me to thinking about the fun I could have had with the millions of lines of code that I had access to. Of course, I didn't do any of these things (though I wish I had done some of the funny ones), and I won't be doing them in the future at my new job either. Let me clearly state that this post is meant to be read as humor. However, it is meant to be informative regarding .NET 3.5 / C# 3.0.

Leaving your job? Being laid off? Here's 4 fun/annoying/destructive things to leave behind!




4. Refactor random methods into operator overloads
(rated: annoying)


Find some methods throughout the code that match operator parameter lists and replace them with operator overloads.

Example:
change this:

public void MyMethod() 
{ 
    //does something 
}
into this:
public static int operator ~ (TheClass c) 
{ 
    //do the same thing referencing "c" instead of "this" 
}
or change this:
public string MyOtherMethod(string something)  
{  
    //does something  
}
into this:
public static string operator + (TheClass c, string something)  
{  
    //do the same thing referencing "c" instead of "this"  
}
Then go through all the broken code and adjust it to use the overloads instead of the methods. This would make the code TERRIBLY confusing!

I
magine seeing:
MyClass m = new MyClass();
~m;
string answer = m + "Jedi";
Greatest part about this annoyance is that "Find References" doesn't work on overloads, so beginner programmers are left stumped; Especially with the "~" overload as many people have never even seen that before outside of destructors!



3. Create Extension methods with hilarious names on base objects
rated: funny


Find some obscure cs file deep within the code, and add this at the bottom:


namespace System
{
    public static class HaHa
    {        public static void ThatsWhatYourMotherSaid(this object o)        {
        }    }}

Now every object in the entire codebase has a useless method called "ThatsWhatYourMotherSaid". Maybe I'm a geek, but that's hilarious. Note: this is easily findable with a "Go to definition" context option.
If you'd rather be annoying instead of funny, do the same thing, but write a program to generate code creating methods for every English word in the dictionary. That would render Intellisense useless - and possibly even cause major IDE slowdown (I didn't try!).

This works well because we put the class "HaHa" in the namespace "System". This namespace is included in every C# file ("using System;"), unless it's been strangely removed. Extension methods are only revealed on objects if the namespace in which they are defined is included (yeah, that's why you have "using System.Linq;" in your code!).




2. Create seemingly useful extension methods which do nothing, or worse...
rated: annoying at the least, possibly destructive

Once again, find some obscure file to hide this in. Similar to above, create an extension method but this time make it sound useful. New people, or beginners joining the project may think, "Wow! That's great!". Here's some examples I can think of:


namespace System
{    public static class HaHa
    {        public static bool EqualsCaseInsensitive(this string s1, string s2)        {
            return true;
        }        public static void ShowOnTop(this Form f)        {            f.Close();
        }
    }
}

Now your strings have a "EqualsCaseInsensitive" method which always returns true, and your forms have a "ShowOnTop" method that closes the form (which also calls Dispose() I believe)! Evil....



1. Replace a widely used core library class with a creatively destructive decorator class
rated: Extremely destructive

Creating a decorator (aka wrapper) class for a core framework class which has the exact same name will allow existing code to compile, but you gain control over it's behavior. The issue here is that if you define a class in local code under the same namespace as a framework class, it will be used instead of the framework class. Here's an INCOMPLETE example:



namespace System.Threading
{
    public class Thread
    {
        private global::System.Threading.Thread _wrappedThread;
        public Thread(ThreadStart start)        {            _wrappedThread = new global::System.Threading.Thread(start);        }
        .
        .
        .
        public void Start()
        {
            if (new Random().Next(1, 101) >= 99)
            {
                return;
            }
            else
            {
                _wrappedThread.Start();
            }
        }        .        .        .
    }
}

To make this example complete, you'd have to decorate every method, property, and event on the Thread class. Tedious, but not too bad with a program to generate the code. Note the usage of "global::" which makes it use the REAL Thread class.
Bottom line is, with the above example (if completed), you'd end up with System.Threading.Thread.Start() only starting 98% of the time. Now THAT is a bitch!

Cheers,
The Software Jedi

1 comment:

Anonymous said...

So... Awsome...