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
{
public:
    Employee(){}
    virtual ~Employee(){}
    virtual void DoWork() {
        cout << "C#, VB.NET, J#" << endl;
    }
};
class Manager : public Employee { public: Manager(){} virtual ~Manager(){} void DoWork(){ cout << "Outlook, powerpoint" << endl; } }; void MakeEveryoneWork(Employee emp,
Employee *empPtr,
Employee& empRef) { emp.DoWork(); empPtr->DoWork(); empRef.DoWork(); cout << endl << endl; } int main(int argc, char* argv[]) { Employee *emp = new Employee; MakeEveryoneWork(*emp, emp, *emp); emp = new Manager; MakeEveryoneWork(*emp, emp, *emp); return 0; }
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.