C# Tips part-III
Posted On September 19, 2007 by Sneha Philipose filed under
C# Tips part-III
Changing a Field to a Property
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"; } } |
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"; }
}
}
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.
Slicing and C#
Yesterday I discussing slicing with Manish. Since a lot of folks move into C# from C++, there is an initial tendency of carrying your old baggage of programming fears, gotchas at the back of your mind. Slicing ranks high in this list. Consider the following code
class Employee |
out put
C#, VB.NET, J#
C#, VB.NET, J#
C#, VB.NET, J#
C#, VB.NET, J#
Outlook, powerpoint
Outlook, powerpoint
Here Manager derives from Employee and overrides the DoWork function. The MakeEveryoneWork function accepts all the three types of parameter passing techniques, by-value, by-pointer, by-reference. First an object of Employee is passed to it and then Manager is sent. In the case of passing by-value slicing occurs and Employee::DoWork gets called instead of Manager::DoWork as highlighted in Red.
Slicing was a major pain point in C++ code, surfacing in parameter passing, exception catch blocks (catch a base type instead of the most-derived type) and other places. So most C++ programmers in the back of their head have a slicing filter running. However, things have suddenly become easy with C#. There is no call by-value for reference types and hence the whole story of slicing is suddenly not there.
Spell check as an OS service
As Operating systems are maturing different features are finding its way into it. So much so that many software are totally becoming redundant as there USP is already a core OS feature.
Recently I needed to include some spell-checking in a software that I was writing. I used interop in MS Office (Word in particular) to get this done. Since spell checking is so widely used I do think they should now become part of Windows. It'd be great if the context menu of text boxes have some think like "Check spelling" along with Cut/Copy/Paste.
The issue is not that things like spell checking is hard to do. The issue is including new dependencies. Now I have a 30 line code that uses Word for spell checking but can I rely on MS Word being installed on all machines where the software will be deployed? This is where OS support comes into play. Someone even suggested using Web-services to get this done!!! That is simply not feasible both from perf as well as security reasons...
The code I used goes as follows....
| ......................................................................... private ApplicationClass m_winword; |
This can be used as in
SpellCheck spellCheck = new SpellCheck();
if(!spellCheck.IsCorrect(someWord))
// not correct message
I love object and collection initializers
This is the my fourth post in the series of posts I am making on C#3.0. See the previous posts here, here and here
Object and collection initializers are new features in C#3.0 which is syntactic sugar over how you allocate and initialize objects and collections.
Object Initializers
Lets consider a class
| .......................................................................... { public string name; public string address; int age; public int Age { get { return age; } set { age = value; } } } |
if I wanted to create a object of the type customer and fill up the public variables and properties
then in C#2.0 I need to do something like
| .......................................................................... Customer customer = new Customer(); customer.name = "Abhinaba Basu"; customer.address = "1835 73rd Ave NE, Medina, WA 98039"; customer.Age = 99; |
With the new object initializer syntax it possible to do all of the above in one statement as in
| .......................................................................... |
This not only reduces lines of code but increases flexibility a lot. So no more being forced to write 5 overloads of a contructor that just accepts these variables and assigns them to fields.This syntax works for both public fields and properties.
In case the class contains other classes as fields then the same statement can also initialize the contained class (see code below in bold).
| .......................................................................... class Phone { public int countryCode; public int areaCode; public int number; } class Customer { public string name; public string address; public Phone phone; } static void Main(string[] args) { var cust = new Customer{name = "Abhinaba Basu", phone = new Phone {countryCode = 1, areaCode = 425, } |
This piece of code is equivalent to the following C#2.0 code
| .......................................................................... Customer customer = new Customer(); customer.name = "Abhinaba Basu"; customer.address = "1835 73rd Ave NE, Medina, WA 98039"; Phone __phone = new Phone(); __phone.countryCode = 1; __phone.areaCode = 425; __phone.number = 9999999; customer.phone = __phone; |
Collection Initializers
Collection initializer is a natural extension to object initializer. It consists of a list of initilializer for each of the elements in a collection seperated by comma and encosed in {}. For a simple List<int> it is as follows
| .......................................................................... |
For the Customer and Phone number class discussed above the collection initializer will look like
| .......................................................................... List<Customer> custList = new List<Customer> { new Customer { name = "Samrat", address = "NJ, USA", phone = new Phone {countryCode = 91, areaCode = 999, number = 8888888} }, new Customer { name = "Kaushik", address = "Behala, Kolkata", phone = new Phone {countryCode = 91, areaCode = 33, number = 3333333} }, new Customer { name = "Rahul", address = "Kerala", phone = new Phone {countryCode = 91, areaCode = 00, number = 4444} } }; |
Just trying to write the above piece of code in C#2.0 syntax shows how cool this new feature is.
You can reach author from the following email-id abhinaba@gmail.com
