I am a developer at Microsoft and work in the .NET Common Language Runtime (CLR) team. For the last 4 years I have been working on virtual machine technologies on a variety of form factors including desktops (Windows, Linux), tablets (Win8), gaming-consoles (Xbox 360), mobile devices (Windows Phone 7, Windows CE, Symbian).I have worked on various core pieces of the runtime including Garbage Collector, memory manager, platform abstraction layer, runtime-performance, etc.Before working on .NET I worked on Visual Studio Team Foundation Server, Visual Studio Team System, Adobe Framemaker, Adobe Acrobat, Texas Instrument's Code Composer Studio.
Unfortunately I had not experimented with Monad before. Yesterday our blog server got swamped with new posting on PowerShell blog, a little poking around revealed that Monad has been renamed to PowerShell. I couldn't believe my eyes, I had expected that it'd be remaned to Microsoft Windows Shell.NET 2007 Professional Edition :)
So feeling a bit guilty I installed it on a XP box and started poking around. So to see the help I tried the following
PS C:\> dir -? NAME Get-ChildItem SYNOPSIS Retrieves the child items <snipped> DETAILED DESCRIPTION Gets the child item(s) <snipped> USAGE Get-ChildItem [[-Path] <System.String[]>] [-Incl <snipped>
I was surprised to see the help looked like Man pages!! Moreover the .NET backbone raised its head (intentionally) when parameter types are shown as System.String. I loved the fact that most common shell commands like dir, del have been aliased to corresponding PowerShell (MSH) commands.
The help was huge and I just wanted to see the usage and I tried the following
PS C:\> (get-command Get-ChildItem).definitionGet-ChildItem [[-Path] <String[]>] [[-Filter] <String>] [-Include <String[]>] [-Exclude <String[]>] [-Recurse] <snipped>
This proves the true power of a object-oriented shell. You can just use the fields/properties as in .definition!
I wanted to find large files in a folder which were not log files and I could do it as
PS C:\> get-item .\* -exclude *.log | sort Length -descending Directory: Microsoft.PowerShell.Core\FileSystem::C:\Mode LastWriteTime Length Name---- ------------- ------ -----a--- 3/7/2006 6:19 PM 1440024 img2-001.raw-a--- 3/17/2006 5:37 PM 423589 FuncTest.zip----- 10/22/2004 7:47 PM 294512 NTLDR----- 3/25/2003 6:00 AM 278688 CMLDR-a--- 10/26/2004 2:16 PM 145466 uiprestore.cmd-a--- 10/5/2005 4:16 PM 141415 rss2.html<snipped>
The other thing I tried out just bowled me over and I instantly made PowerShell my default shell. I wanted to rename a registry key and I was able to do it as follows
PS C:\> cd HKCU:PS HKCU:\> cd 'HKCU:\Software\MyCompany\'PS HKCU:\Software\MyCompany> ren MyProd MyCompany_orgPS HKCU:\Software\MyCompany> dir Hive: Microsoft.PowerShell.Core\Registry:: HKEY_CURRENT_USER\Software\MyCompanySKC VC Name Property--- -- ---- -------- 1 0 MyCompany_org {} 1 0 Licensing {}
So I was just able to use the registry seamlessly as the file-system, list keys using dir and delete using del!! Regedit RIP. I guess the next target of Team Foundation source control would be create a provider to integrate with this model.
I've just experienced the future of all shells and just wanted to share my excitement with fellow developers. This is one big success story for .NET
Well the title is partially true. But first a quick recap of what is object initializer and why I love them.
Recap
In C# 3.0 (will ship with next version of Visual Studio) if you have public properties/fields in a class as follows, then you can directly assign values to them while creating instance of the class.
class Customer{ public string name; public string address; int age; public int Age { get { return age; } set { age = value; } }}var cust = new Customer{name = "Abhinaba Basu", address = "1835 73rd Ave NE", Age = 99 };
class
{
}
So no need of creating the object first and using a statement each for each of the assignments. Read further about this and the syntactic sugar behind this here.
Custom Attributes and object initialization
Custom attributes supported something like this all along. It worked for public properties and fields, but worked only for custom attributes and not for all classes. Consider the custom attribute definition
[AttributeUsage(AttributeTargets.All)]public class DescriptionAttribute: Attribute{ public DescriptionAttribute(string description) { this.description = description; detailedDescription = string.Empty; } public string Description { get { return description; } } public string Detailed { get { return detailedDescription;} set { detailedDescription = value; } } private string description, detailedDescription;}[Description("Nice class", Detailed = "Detailed descr")]class MyClass{}
[
If you notice carefully this is special syntax and when the atrribute is being applied to MyClass we are using property=value inside the attribute initialization code. This syntax is similar to object initializer. Here Detailed is called the optional argument for the attribute.
You can get to the custom attribute using something like
MyClass mc = new MyClass();object[] attrs = mc.GetType().GetCustomAttributes(true);if (attrs != null && attrs.Length > 0){ DescriptionAttribute descr = (DescriptionAttribute)attrs[0]; Console.WriteLine(descr.Description); Console.WriteLine(descr.Detailed);}
MyClass
Some developers believe that object cloning (creating new object which are copies of the original) is easier in C# than in other languages like C++. However, I do not agree with this. Somewhere I had read that a good language is one that places more hardship on framework (class) designers and less on client developers. This is where we find the principle getting violated.
C++
Lets consider a class that uses dynamically allocated memory and needs deep-copy when it is cloned. In the C++ world the developer of the class had to know things like copy-constructor and = operator overloading (and when they get called) to ensure that this happens correctly. A well-behaved class would look like
class MyClass{public: MyClass() // ctor { numListLen = 10; numList = new int[numListLen]; } MyClass(const MyClass& mc) // copy ctor { numListLen = mc.numListLen; numList = new int[numListLen]; for(int i = 0; i < numListLen; i++) numList[i] = mc.numList[i]; } MyClass& operator=(const MyClass& mc) { if(this != &mc) // take care of mc = mc assignement { delete[] numList; numList = new int[numListLen]; for(int i = 0; i < numListLen; i++) numList[i] = mc.numList[i]; } return *this; // take care of mc1 = mc2 = mc3 } virtual ~MyClass() { delete []numList; } int* numList; int numListLen;};
numListLen = 10; numList =
All this code just to ensure that copy happens as planned. So people call it complex. However, the client uses this class as.
MyClass mc1, mc2; // class Ctormc2 = mc1; // calls = operator overloadMyClass mc3 = mc1; // calls copy-ctormc1.numList[2] = 2;// mc2, mc3 are left untouched
MyClass mc1, mc2;
So the client programmer simply need not care about shallow/deep copy. He assigns and creates object and all of the deep-copy stuff are handled under the hood.
C#
On C# you cannot overload the assignment operator and copy-ctor is not supported. The object cloning is supported using the ICloneable interface. Consider the following code that implements this interface
class MyClass : ICloneable{ public MyClass() { deepRef = new AnotherClass(); } public object Clone() // ICloneable implementation { MyClass mc = this.MemberwiseClone() as MyClass; mc.deepRef = this.deepRef.Clone() as AnotherClass; return mc; } public AnotherClass deepRef;};
The code looks much simpler. However the catch is that the client writer needs to ensure that he never creates an object copy by direct assignment. So if he does the following there goes a bug into his code
MyClass mc1 = new MyClass();MyClass mc2 = mc1; // Bug - shallow copy mademc1.deepRef.x = 10;// and mc2.deepRef gets modified
mc1.deepRef.x = 10;// and mc2.deepRef gets modified
So the client needs to call MyClass mc2 = mc1.Clone() as MyClass; to ensure deep copy. Since humans do forget bugs like this creep in.
Another issue is that ICloneable came in the pre-generic (read pre-historic) era. So its not type safe and you need ugly type-casting all over the code.
Ruby
ruby which was once a upon a time my favorite language sucks big time in deep-copy. You need to do something as below to get a deep copy
class Object def deepcopy Marshal::load(Marshal.dump(self)) end end
In the old days (sigh!!!) when I used to code in C++, I unfortunately had a friend with a knack of doing/finding weird ways of programing. One day he asked me the following question
How do you write a program in C++ which does not have any looping construct and yet it can print a string n-times, even though the string is present only once in the source file and its not called multiple (n) times.
The answer goes as
#include <iostream>using namespace std;class MyClass{public: MyClass() { cout << "Hello World" << endl; }};int main(int argc, char* argv[]){ MyClass mc[10]; return 0;}
#include
In C++, classes are not reference types and when you declare an array as above you actually create an initialized array of objects on the stack. So all the n-elements of the arrays is allocated and initialized by calling its default constructor. So for a n-element array the ctor is called n-times and you can print the string as many times using this.
Why would someone ever need to do something like this, beats me :). This became a sort of joke between us and when I joined MSFT and started working on .NET and sent him an email, saying that I was happy working in a language where you cannot do this kind of a thing.
When I first saw the bullet in the feature list of C# 3.0 that read "collection initializer" I was a bit scared. I thought maybe C# would support some construct in which the compiler will initialize all the elements of a collection/array by allocating the element with calls to default/some ctor. Fortunately thats not the case. For an example on object/collection initializer in C# 3.0 see here.
I have a program that needs to print the results of a query. So I create a localizable string, use string.Format and print the results as in
Your query returned 5 results.
This looks good. Now a tester assigned to test this tried another query and got back
Your query returned 1 results.
And oops there goes a bug on my name. The question is how do I solve it. I have three options. Leave it as it is, make it result(s) or have two strings and switch between the two so that I get.
Your query returned 5 results.Your query returned 1 result.
I am sure most users will immediately want me to use the 3rd option because it is the correct solution. The problem is that this has heavy localization, test and maintenance cost. Consider the following code that I need to use to get that done
if (resultCount == 1) str = string.Format(singular, resultCount); else str = string.Format(plural, resultCount);
you can use tertiary operator for above but that complicates things further.
This piece of code needs testers to test both code paths, localization team to localize double the number of string in all supported languages. Some change in code need to be done at two places. Some costs are straight forward, outsourced localization is often charged per string localized :)
Even after that subtle errors creep in. For example the tester needs to ensure that in case of 0, 0 results is shown and not 0 result.
So the first two solutions appear to be better. However result(s) though popular choice before do not work any more. Screen-readers used by the visually-impaired fail on this. Modern style-guidelines favor 1 results over 1 result(s).
So next time you see a program show 1 results, don't consider the programmer to be grammatically challenged :)
When you change a field to a property you need to re-build all code that used that field.
Even though it might be obvious to many but it isn't to at least some people. The reason is that the client code exactly remains the same!!! In one of the internal DLs someone raised this as a potential .NET bug. Lets look into the code
He had a class library that looked something like
using System;namespace FieldToProp{ public class MyClass { public string Author = "Abhinaba"; }}
using
This class library is accessed from a client application as
MyClass mc = new MyClass();Console.WriteLine(mc.Author);
Now the field Author is changed to a property with the same name
public class MyClass{ public string Author { get { return "Abhinaba"; } }}
public
Since a property is used with the same syntax as a field the user expected the same client binary to just work when he dropped the new class-lib assembly. However, he got the exception "System.MissingFieldException: Field not found: 'FieldToProp.MyClass.Author'". On rebuilding the client the issue gets resolved.
The reason is that when a property as above is present in a class a method with the following MSIL signature is generated
.method public hidebysig specialname instance string get_Author() cil managed
So the property needs to be called from the client as a method call.
callvirt instance string [FieldToProp]FieldToProp.MyClass::get_Author()
The compiler figures out that the target is a property and inserts the appropriate method call. However when the reference is to a filed the following MSIL is used in the client.
ldfld string [FieldToProp]FieldToProp.MyClass::Author
So without re-building the whole thing just doesn't work.
For folks missing my posts (are there any such people :) ) I am back from vacation. I was getting scorched in the hot Mumbai sun and then I was chilling out in Daman or in the Buddhist caves in the western Ghat.
I was welcomed home with a long list of bugs and emails, emails and more emails. As someone who joined MS recently said "Man!!! it rains emails here"
Me getting baked in Juhu Beach
Chilling out in Cidade De Daman. Obviously I'm not in the frame as I took the picture and was juggling 2 beer cans and my camera at that time ;^)