Q:

Why do I need an explicit downcast if my object of type "object" is pointing to the correct instance in hierarchy?

Consider the following inheritance:
abstract class Employee
{
     private string empID;
     private string empName;
}   

class SoftwareDeveloper : Employee 
{
    ............    
}

class MarketingPerson : Employee
{
    ........... 
}

static void Main()
{
    Employee Jaffer = new SoftwareDeveloper();
    Employee George = new MarketingPerson();

    // Ok because of is-a relationship    
    LayOff(Jaffer);

    // Ok because of is-a relationship    
    LayOff(George);

    object Leo = new MarketingPerson();

    // Error because downcast is required as (MarketingPerson) Leo
    LayOff(Leo);
}

static bool LayOff(Employee emp)
{
    // some Business Logic
    return true;
}

Even though the declaration object Leo = new MarketingPerson() points to an instance of MarketingPerson, why do I need to downcast?

A:

You need to cast because the compiler only knows the declared types.
In your example, object Leo = new MarketingPerson();, you are declaring that the variable Leo is of type object. You can put a MarketingPerson (or anything else) in that variable, but it's still declared as an object.
The LayOff method is declared as accepting an Employee - as object does not derive from employee, you need to cast it to tell the compiler "I am forcing this object into an Employee

