Monday, September 29, 2008

Refactoring (Part 2)

  • Introduce Foreign Method
    Create a method in the client class with an instance of the server class as its first argument.
  • Introduce Local Extension
    Create a new class that contains these extra methods. Make this extension class a subclass or a wrapper of the original.

    Organizing Data:
  • Replace Data Value with Object
    Turn the data item into an object - during initial stages of development, your data is simple. As development proceeds you realize that those simple items aren't so simple anymore - turn it into an object.
  • Duplicate Observed Data
    You have domain data available  only in a GUI control, and domain methods need access - Copy the data to a domain object. Set up an observer to synchronize the two pieces of data.
  • Change unidirectional Association to Bidirectional
    You have two classes that need to use each other's features, but there is only a one-way link - Add back pointers, and change modifiers to update both sets.
  • Replace Magic Number with Symbolic Constant

Sunday, September 28, 2008

Refactoring (Part 1)

  • Replace Temp with Query
    Extract the expression into a method. Replace all reference to the temp with the new method. The new method can then be used in other methods.
  • Introduce Explaining Variable
    Put the result of the expression, or parts of the expression, in a temporary variable with a name that explains the purpose.
  • Split Temporary Variable
    Do not reuse the same temp variable, make a separate temporary variable for each assignment.
  • Remove Assignments to Parameters
    Function arguments should not be re-assigned inside the function.
  • Replace Method with Method Object
    Turn the method into its own object so that all the local variables become fields on that object. You can then decompose the method into other methods on the same object.
  • Substitute Algorithm
    Replace the body of the method with some new algorithm.

When to refactor

When you add a function
When you need to fix a bug
When you do a code review

The rule of 3 :
1st time you write some code
2nd time you do something similar, you sill do it
3rd time you do something similar, you refactor.

Wednesday, September 24, 2008

C# : events

Custom eventargs do not need to to use a new custom delegate, you can simply say

public event EventHandler<myEventArgs> NewData;

Why is sender of type object??

  1. if you inherit the event, you would still need to cast to the derived class, so might as well cast from object.
  2. delegate can be used by other types too.

all eventhandlers have return type as void, since there is no way to get the return values from all of the function registered.

The method to raise the event should be - protected virtual.

Use a temp variable to ensure type safety. i.e.

EventHandler<NewMailEventArgs> temp = NewMail;

if(temp !=null) temp(this,e);

You have System.Reflection.EventInfo

As long as an object has registered one of its methods with an event, the object cant be GCed, so unregister events in Dispose().

Registration or un-registration - only one should be executed at a time, so they are marked with [MethodImpl(MethodImplOptions.Synchronized)]. When MethodImpl attribute is applied to an instance method, the CLR uses the object itself as the thread-sync lock, this means that if a class is defines many events, all reg/un-reg methods use the same lock and this hurts scalability, if you have multiple threads reg/un-reg on different events simultaneously.

Thread-synchronization guidelines state that methods should not take a lock on the object itself because the lock is exposed publicly to any and all code. This means that anyone could write code that locks the object, potentially causing other threads to deadlock.

for robust implementation - explicitly control event reg/un-reg

value types can have events - no synchronization.

Friday, September 19, 2008

Running C++ programs in VS2008

I wanted to brush up my C++ skills, write link list/tree programs, however I my simple hello world program was not compiling in VS2008 -- It kept saying iostream.h file not found.

Here's how I got it running :

After starting a new Win32 project, in the wizard, I unselected "Use Precompiled Header".

Now the following code compiles and runs.

#include "stdafx.h"
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
cout<<"Hello World"<<endl;
return 0;
}



stdafx.h already includes stdio.h and tchar.h, so we can also move #include <iostream> to stdafx.h

Tuesday, September 16, 2008

C# : Strings (Part 1)

Strings are immutable, so to perform a lot of string manipulations efficiently, use the StringBuilder class.

Having strings as immutable means there are no threads synchronization issues.
Also CLR can share multiple identical String contents through a single String object - String interning

String class is sealed.

To compare string without culture information use :
StringComparision.Ordinal or StringComparision.OrdinalIgnoreCase -- fastest.

Instead of lowercase, convert strings to uppercase using ToUpperInvariant()
Microsoft has optimized the code for performing uppercase comparision. In fact, the FCL normalizes strings to uppercase prior to performing case-insensitive comparisions.

Your code will be easier to read and maintain it you always indicate how you want to perform your string comparisions.

Strings cannot actually be changed--only new ones can be created. Therefore, Replace will repeatedly create new strings. StringBuilder, however, can be changed internally and no new copies will be created on Replace or Insert, so if you need to replace or insert very often, use StringBuilder

Given two string variables, how can one get both string variables to point to the same memory location?

Sunday, September 14, 2008

C# : List<T> vs. ArrayList

The generic collection class offers many improvements over the non-generic equivalents.

1. API is clean and improved
2. Performance is greatly improved
3. Value Types need not be boxed when used with List - so no GC
4. Provides compile time safety

C# : Value Types

VT == ValueTypes
RT == ReferenceTypes

VT are simple types - they do not carry storage overheads -->this reduces the cost of creating a object since VT do not have object header, method invocation against a VT does not use virtual method dispatch - this helps performance but loses some flexibility.
VT dont have sync block index, so multiple threads cannot synchronize their access over a VT
VT have System.ValueType as base type.
VT are - structs,enum,bool,int family,etc
VT are marked as sealed and cannot be used as base type.
VT are allocated on stack and not heap,
VT cannot have finalizers
VT cannot have default constructors
VT can be boxed or unboxed, RT are always boxed
VT variables always contain a value of the underlying type - VT variable is never null
when you assign a VT to another, a field by field copy is made.
VT have a different .Equals and .GetHashCode method from RT.(overloaded by System.ValueType)

Defining custom VT - using enum or structs constructs

struct types -
cannot have explicit base class it is always System.ValueType
cannot declare struct as abstract or sealed, compiler implicitly adds sealed - cannot inherit from structs
has LayoutKind.Sequential attribute

When to declare types are VT
1. When the type is simple, that has no members that modify any of the type's instancec feilds, when a type offers no members that alter its fields, we say the type is immutable
2. The type doesn't need to inherit from any other type
3. the type wont have any other types derived from it.
4. Instances of the type are small (16 bytes or less)
5. Instances of the type are large(>16bytes) and are not passed as method parameters or returned from methods.

Saturday, September 13, 2008

C#: new vs. override (part 2)


Derived:Base
Base:BaseBase
BaseBase:BaseBasebase

Derived d = new Derived();
BaseBasebase bbb = d;
BaseBase bb = d;
Base b = d;

All these classes have functions as follows :

bbb - virtual public void FooChain()
bb - override public void FooChain()
b - virtual new public void FooChain()
d - override public void FooChain()

Then the result is as follows:

bbb.FooChain();//BaseBase FooChain
bb.FooChain(); //BaseBase FooChain
b.FooChain(); //Derived FooChain
d.FooChain(); //Derived FooChain

In a hierarchy when we use new(as in Base class), it breaks the chain, so now, when bbb.FooChain() is called, the type is BBB, and as per our rule "overide execuetes derived" and FooChain() in the actual object of D is overridden, we get the most derived FooChain() which is not a "new" Function, so we get "BaseBase FooChain".

C# : Initializers and Constructors

When ctor is executed, it is executed as follows :
ctor
{
initializers;
base();
code of current ctor();
}
Hence, when you have a long hierarchy of classes, you see that initializers run from D -> B and constructors run from B -> D.
Okay, now thats a fact, but why does this happen? --> Derived ctor may rely on state initialized by base ctor... how? --> base may contain a variable which is initialized in base ctor, and dervied ctor might be using that variable.

You should avoid virtual method calls in a ctor of a non sealed type why? --> If a base type ctor causes a virtual method call to be invoked, the most derived type's method will be dispatched even though the derived type's ctor has not completed execution. And so there might be null ref exceptions or unpredictable results.

C# : new vs. override

new:

  • just to be sure that you intentionally want to hide the base method
  • no base method - derived used new --> compiler warning Warning 1 'Types.Derived.Foo()' hides inherited member 'Types.Base.()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.
override:
  • derived has to explicitly override that base method.
  • base has Foo(int) and derived overrides, then if base changes the signature to Foo(long) then derived no longer overriders it, it has its own function. Error 2 'Types.Derived.FooNotInBase()': no suitable method found to override.

If you upcast, then "new" executes base and "override" executes derived.

Base b = new Derived();
Derived d = new Derived();
b.FooWithNew(); //Base FooWithNew
b.FooWithOverride(); //Derived FooWithOverride
d.FooWithNew(); //Derived FooWithNew
d.FooWithOverride(); //Derived FooWithOverride

In C#, functions are overloads are impemented as "hide by signature", so if base has Foo(int) and Foo(long) and Derived as Foo(int) then Foo(long) from base is not hidden.