tags:

views:

114

answers:

2
interface I { int J(); }

class A : I
{
   public  int J(){return 0; }  // note NOT virtual (and I can't change this)
}

class B : A, I
{
   new public int J(){return 1; }
}


B b = new B();
A a = b;
I ib = b, ia = a;

b.J(); // should give 1
a.J(); // should give 0 (IMHO)

ia.J(); // ???
ib.J(); // ???

I know I could just try it but I'm looking for a good authoritative source for this whole corner and I'd rather not just start myopically digging through the MSDN texts (I haven't a clue what to Google for).

+1  A: 

It does not matter that you are talking to the contract provided by a base class or interface they will all return 1 because you are talking to an instance of class B.

John Downey
do you have a link to an official reference? I'm more looking for "the rest of the story" than this exact question.
BCS
C# is a single dispatch language meaning the method to be invoked is determined by the type of the object in all your cases the type is B.
John Downey
+2  A: 

Rewritten: Since we're talking about implementing IDisposable what really matters is ensuring that both the Derived and Base classes have the opportunity to run their respective cleanup code. This example will cover 2/3 of the scenario's; however since it derives from Base() and Base.Dispose() is not virtual, calls made to ((Base)Child).Dispose() will not provide the Child class with the chance to cleanup.

The only workaround to that is to not derive Child from Base; however that's been ruled out. Calls to ((IDisposable)Child).Dispose() and Child.Dispose() will allow both Child and Base to execute their cleanup code.

class Base : IDisposable
{
    public void Dispose()
    {
        // Base Dispose() logic
    }
}

class Child : Base, IDisposable
{
    // public here ensures that Child.Dispose() doesn't resolve to the public Base.Dispose()
    public new void Dispose()
    {
        try
        {
            // Child Dispose() logic
        }

        finally
        {
            // ensure that the Base.Dispose() is called
            base.Dispose();
        }
    }

    void IDisposable.Dispose()
    {
        // Redirect IDisposable.Dispose() to Child.Dispose()
        Dispose();
    }
}
STW
I can't alter the base class (it's one of .NET's class) and the method in question is NOT virtual so I can't do your best practices in this case. Also in the non virtual case, going from "B : A, I" to "B : A" alters stuff (I tested it and to get the new J to be used, the explicit "I" is needed.
BCS
What .NET class are you working with? An actual example might be more helpful than a math story-problem :)
STW
I'm trying to add stuff to the IDisposable actions for FileSystemWatcher.
BCS
All updated, knowing the particulars got my head out of the "should do" and into the "need to do"
STW