Showing posts with label c#. Show all posts
Showing posts with label c#. Show all posts

Wednesday, August 10, 2011

Object are passed by reference

Passing values in c# is really misunderstood by many people.

Let's understand this concept by few examples:

StringBuilder first = new StringBuilder();
StringBuilder second = first;
first.Append ("hello");
first = null;
Console.WriteLine (second);
 
Output: Hello

When we assign reference to second of first, we are acutally assigning the object reference contact by first. So when we set first to null, now first is not refering to any object, however second is still referening to that object.

Now
void Foo (StringBuilder x)
{
    x = null;
}

...

StringBuilder y = new StringBuilder();
y.Append ("hello");
Foo (y);
Console.WriteLine (y==null);
 
Output: False Interesting right! Actually when we are passing object by reference, we are not passing the actual 
reference to first object, instead we are just passing hte values. 
 
The value of a reference type variable is the reference - if two reference type 
variables refer to the same object, then changes to the data in that object will 
be seen via both variables.

Reference types stored on Head and value types on Stack

We usually think that reference types are stored on the Head, right. Yes we are right.

But we do think that value types are stored on Stack and here we are always not right.

Only local variables are stored in the stack, so what's this local variables? Local variables declared within methods and method parameters live on stack. So when on heap? If they are declared within the class. Value types lives on wherever they are declared. So if they are created in reference type ex, class they would be stored on heap, and if declared locally ex. within method then stack.

Are Structs really lightweight classes?

We usually have very common myth about "Struts" that they are simple and should be used as data transfer types and they are lighter in terms of performance as they do not require garbage collection.

But that is not fact in all cases.

We should be careful while choosing between struct or reference type.

It could more better to pass few bytes of data as reference rather than copying all the data, example passing Hashtable instance. Just imagine if Hashtable is values type, passing whole hashtable instead of the reference. 

Saturday, July 23, 2011

C# Notes

C# important notes:

1.  Delegates provide a way of giving a level of indirection, so that instead of specifying behavior directly, it can be in some way "contained" in an object, which can be used like any other object, where one available option is to execute the encapsulated behavior.

A delegate type is a single-method interface , and a delegate instance is an object implementing that interface.

Delegates are typically used when the code that wants to execute the actions doesn't know the details of what the action should be.

Four things need to happen:

■ The delegate type needs to be declared.
■ There must be a method containing the code to execute.
■ A delegate instance must be created.
■ The delegate instance must be invoked.

Delegate Type :
A delegate type is effectively just a list of parameter types and a return type. It specifies what kind of action can be represented by instances of the type. For instance, consider a delegate type declared like this:

delegate void StringProcessor (string input);

The code says that if we want to create an instance of StringProcessor, we’re going to need a method with one parameter (a string) and a void return type (the method doesn’t return anything). It’s important to understand that StringProcessor really is a type. It has methods, you can create instances of it, pass around references to instances, the whole works.

In .NET, delegate instances always refer to methods.

void PrintInteger (int x)

An instance of that delegate type, specifying that this method be executed when the delegate instance is invoked. Action of the delegate instance.

StringProcessor proc1, proc2;
proc1 = new StringProcessor(StaticMethods.PrintString);

InstanceMethods instance = new InstanceMethods();
proc2 = new StringProcessor(instance.PrintString);

Example 1:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Delegates_28July2011_7PM
{

    //1. Declare delegate type.
    delegate void StringProcessor(string input);

    class Person
    {
        public string Name { get; private set; }


        public Person(string name)
        {
            Name = name;
        }

        //2. Declare compatible INSTANCE method.
        public void Say(string message)
        {
            Console.WriteLine("{0} says: {1}", Name, message);
        }
    }

    class Background
    {
        //2. Declare compatible STATIC method.
        public static void Not(String Note)
        {
            Console.WriteLine("{0}", Note);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Person objPerson1 = new Person("Ram");

            Person objPerson2 = new Person("Shyam");

            //3. Creates three delegate instance
            StringProcessor ramVoice, shyamVoice, background;
            ramVoice = new StringProcessor(objPerson1.Say);
            shyamVoice = new StringProcessor(objPerson2.Say);
            background = new StringProcessor(Background.Not);

            //4. Invokes delegates instance.
            ramVoice("Namaskar");
            shyamVoice("Skhaa");
            background("This is really sweet");

            Console.ReadLine();

        }
    }
}

Tuesday, October 19, 2010

Best Practices for C# Application Development

Decide between Value Types and Reference Types

Whenever you need to create a type, first ask yourself a question “What you want and Why you want?”. If you could answer your question, you can decide between the type you want to use. If you want to store your data, use value types and when you want to create an instance of your type by defining the behavior, use reference types. Value types are not Polymorphic whereas, the Reference types can be. Value types are most efficient in terms of memory utilization over reference types and produces less help fragmentation & garbage. If you want to pass values to a method implementation, decide what you want to do and based upon your requirement, decide between value types and reference types. Use of reference type variables actually change the original value but use of value type will create a copy of the original variable and pass across the method. Thus, protects your original value from accidental changes. Lets see them in real example. In the below code, we are passing the variable “i” as value type and in the method implementation incrementing it by 10. As it was passed by value, you will see the original value “5” as output of the program code.

static void Main(string[] args)
{
int i = 5;
SetValues(i);

System.Console.WriteLine("Currently i = " + i); // will print "Currently i = 5"
}

static void SetValues(int x)
{
x += 10;
}


In the below code as we are sending “i” as a reference, it will change the original value of “i” inside the method and hence you will see 15 as the output in the screen.

static void Main(string[] args)
{
int i = 5;
SetValues(ref i);

System.Console.WriteLine("Currently i = " + i); // will print "Currently i = 15"
}

static void SetValues(ref int x)
{
x += 10;
}


Prefer Runtime Constants over Compile time Constants

Runtime constants are always preferred than the Compile time constants. Here you may ask what is runtime constant and what is compile time constant. Runtime constants are those which are evaluated at the runtime and declared with the keyword “readonly”. Other side, compile time constants are static, evaluated at the time of compilation and declared with the keyword “const”.

public readonly string CONFIG_FILE_NAME = "web.config"; // runtime constant
public const string CONFIG_FILE_NAME = "web.config"; // compile time constant


So, what is the need to prefer readonly over const variables? Compile time constants (const) must be initialized at the time of declaration and can’t be change later. Also, they are limited to only numbers and strings. The IL replaces the const variable with the value of it over the whole code and thus it is a bit faster. Whereas, the Runtime constants (readonly) are initialized in the constructor and can be change at different initialization time. The IL references the readonly variable and not the original value. So, when you have some critical situation, use const to make the code run faster. When you need a reliable code, always prefer readonly variables.

Prefer “is” and “as” operators while casting

It is better to use “is” and “as” operator while casting. Instead of Explicit casting, use the Implicit casting. Let me describe you with the example of a code.

// this line may throw Exception if it is unable to downcast from Person to Employee
var employee = (Employee) person;


In the above code, suppose your person is a Customer type and when you are converting it to Employee type, it will throw Exception and it that case, you have to handle it using try{} catch{} block. Let’s convert the same using “is” and “as” operators. See the below code:

// check if the person is Employee type
if(person is Employee)
{
// convert person to Employee type
employee = person as Employee;
}

// check if the person is Customer type
else if(person is Customer)
{
// convert person to Customer type
customer = person as Customer;
}


In the above code you can see that, in the second line I am checking whether the person is a Employee type. If it is of type Employee, it will go into the block. Else if it is a Customer type, will go to the block at line 12. Now, convert it with the “as” operator, as shown in the line 5. Here, if it is unable to convert, will return as null but will not throw any exception. So, in the next line you can check whether the converted value is null. Based on that, you can do what you want.

Always prefer the foreach(…) loop

Rethrow exception and InnerException property in .NET

In the example below, we have re-thrown exception with only a friendly message in the constructor method.

private void DivideOperation()
{
try
{
int x = 5;
int y = 0;
int result = x/y;
}
catch (Exception ex)
{
throw new DivideByZeroException(“Invalid operands were given.”);
}
}


This is, of course, not a good practice to do exception handling. So to preserve the details of the original exception, we have to pass the exception object as a second parameter in addition to friendly message as:

private void DivideOperation()
{
try
{
int x = 5;
int y = 0;
int result = x/y;
}
catch (Exception ex)
{
throw new DivideByZeroException(“Invalid operands were given.”, ex);
}
}