A world apart from the everday ...

Assert.IsTrue(Entries.Count == 0);

November 2005 - Posts

when to pass byRef and when to pass byVal
I realise that you all think this topic has been covered at nauseam in the past but I was horrified recently in an interview when I asked a question at the response I got from a number of so called "senior C# developers". So then I thought I'd check with colleagues, friends, shopkeepers, gardners, pets, in fact everybody hoping and praying to get a decent answer ... surprisingly I got very few correct answers.

So let me now ask the .net development community of SA the following question, and before looking further for the answer and my explanation try and answer this for yourselves. I'd be interested to know your thoughts on this (common i said no cheating!)

What is the output from the following code extract:-


1    using System;
2    namespace ConsoleApplication2
3    {
4        class ByRefByVal
5        {
6            static void Main(string[] args)
7            {
8                Foo f = new Foo();
9                f.SomeString = "initial";
10                Console.WriteLine(f.SomeString);
11           
12                DoSomething(f);
13                Console.WriteLine(f.SomeString);
14
15                Console.ReadLine();
16            }
17   
18            private static void DoSomething(Foo myfoo)
19            {
20                myfoo.SomeString = "something new";
21                myfoo = null;
22            }
23        }
24
25        class Foo
26        {
27            public Foo() {}
28            public string SomeString=string.Empty;
29        }
30    }

   

Answer: remember no cheating, you'll thank me for this one day :)
initial
something new

Why Larry, Why? I hear you shout, I passed the foo object into DoSomething byVal why was it changed?

Well did you really pass the foo object into the method call? What really happened here?

We all know the difference between passing value types byval and byref,
If the variable is passed byval any change to the variable value in the called function is not reflected back in the callee because a copy of the variable is passed which is killed upon returning from the called function.
If the value is passed byref it means that the changes will be reflected back because the same variable is passed.

So why did this code produce the result it did?
To answer this we need to take a look at what happens when a reference type is passed by byval.

For ordinary method calls passing a variable as an argument to a method (or property) is logically equivalent to declaring another variable of the same type, and assigning its value to the newly-declared variable.
No surprise, there. For both value- and reference-types, a shallow copy of the variable is made.

For value-types, this means a member-wise copy is created.
For reference-types, only the reference is copied

A Brief Insight into Reference Types:
Data for Reference types is stored on the heap. When creating an instance of a reference type a pointer is created on the stack referencing the memory allocated on the heap to the actual object.
Hence Foo foo = new Foo(); actually returns back the pointer.

Now when this pointer is passed by val a copy of the POINTER is made! This new pointer still points to the same memory on the heap and therfore indirectly to the same object; any changes done to the object in the called method will manipulate the same data to which original foo pointer was pointing.
But notice that when I set foo=null on line 21 nothing happened outside of DoSomething, that's because I never killed the object on the heap, just the myFoo pointer [the byval param of the method] and the original pointer created in the Main method still lives and points happily to the object on the heap.

In case of passing byref, a reference to the original pointer is passed to the called function.
So is there a difference between passing byref and passing byval when dealing with reference types? Yes, but a rather subtle one.

Lets take a look at the slightly modified version of above code:
What do you suppose the output of this code will be?

1    using System;
2    namespace ConsoleApplication2
3    {
4        class ByRefByVal
5        {
6            static void Main(string[] args)
7            {
8                Foo f = new Foo();
9                f.SomeString = "initial";
10                Console.WriteLine(f.SomeString);
11           
12                DoSomething(ref f);
13                Console.WriteLine(f.SomeString);
14
15                Console.ReadLine();
16            }
17   
18            private static void DoSomething(ref Foo myfoo)
19            {
20                myfoo.SomeString = "something new";
21                myfoo = null;
21            }
22        }
23
24        class Foo
25        {
26            public Foo() {}
27            public string SomeString=string.Empty;
28        }
29    }


Now you can see I'm passing around a reference to a pointer.
If you run the above code it breaks because the calling method attempts to access a null object on line 13.
Why you ask, well by setting myfoo = null on line 21 this time I am actually modiying the original pointer created on line 8,
thereby actually whacking the object from the heap.

Based on this you can see why passing reference types byRef is not a great idea, you have no idea whether or not the called function has disposed of your object for you.

As part of my job I get to do regular code review sessions and something I find ALL the time is DataSet objects being passed all over the place byref, when asking the developer why the response is always "to stop new copies of the huge dataset being created each time".

Sorry to burst your little "performance" bubble fella, but passing a dataset byval WILL NOT create a new instance of the object.
You will merely create a new pointer to the same object which you are free to do with as you wish.

Of course this begs the question: Can anybody think of a time when you have to pass a reference type by ref?
Posted: Nov 08 2005, 04:27 PM by Ryan CrawCour | with 8 comment(s)
Filed under:
Interfaces vs Abstract classes
This is a question that keeps coming up, time and time again.

This post is probably going to cause renewed debate on the subject; which is well, GOOD!

So to Interface or not, that is the question....

In order to answer this I feel we should take a quick look at the basic difference's between an Interface and an Abstract class, perhaps this will provide the answer we're looking for.

What is an Interface?

An interface is a contract,  a specification that concrete classes MUST follow. It defines method signatures but cannot have any implementations; the latter must be provided by the classes that implement the interface.

C# differs from C++ in this regard because C++ lacks native language support for interfaces. As a C++ programmers you have to create an interface by defining an abstract class with pure virtual methods.

So what then you ask is an abstract class...

An Abstract class lets you define some behaviors and force your subclasses to provide others.
For example, if you have an application framework, an abstract class may provide default services such as event and message handling. Those services allow your application to plug in to your application framework. However, there is some application-specific functionality that only your application can perform. So instead of trying to define these behaviors, the abstract class can declare abstract methods.

So, now that we know the differences between Interfaces and Abstract classes when do we use which?

1. multiple inheritance
A class may implement several interfaces but can only extend one abstract class.

2. default implementation
An interface cannot provide any code at all, much less default code. An abstract class can provide complete code, default code, and/or just stubs that have to be overridden.

3. adding functionality
If you add a new method to an interface, you must track down all implementations of that interface in the universe and provide them with a concrete implementation of that method.     
If you add a new method to an abstract class, you have the option of providing a default implementation of it. Then all existing code will continue to work without change.

4. is-a vs -able or can-do
Interfaces are often used to describe the abilities of a class, not its central identity, e.g. an Automobile class might implement the Recyclable interface, which could apply to many otherwise totally unrelated objects.

An abstract class defines the core identity of its descendants.

If you defined a Dog abstract class then Poodle descendants ARE Dogs, they are not merely dogable.

Implemented interfaces enumerate the general things a class CAN DO, not the things a class IS.

This to me is the ultimate decision factor between inheritance and interfaces.

So that should make it completely clear as to when to use an Interface or an Abstract class, Or does it?
Posted: Nov 07 2005, 01:03 PM by Ryan CrawCour | with 10 comment(s)
Filed under: