Click here to Skip to main content
15,895,709 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
public class Program
    {
        static void Main(string[] args)
        {
            Document theNote = new Note("Test Note");
            IStorable isNote = theNote as IStorable;

            if (isNote != null)
            {
                isNote.Read();
                isNote.Write();
            }

            Console.WriteLine("\n");

            theNote.Read();
            theNote.Write();

            Console.WriteLine("\n");

            Note note2 = new Note("Second Note");
            IStorable isNote2 = note2 as IStorable;

            if (isNote2 != null)
            {
                isNote2.Read();
                isNote2.Write();//see this output            
            }

            Console.WriteLine("\n");

            note2.Read();
            note2.Write();

        }
    }

    interface IStorable
    {
        void Read();
        void Write();
    }

    public class Document : IStorable
    {
        public Document(string s)
        {
            Console.WriteLine("creating document with: {0}", s);
        }

        public virtual void Read()
        {
            Console.WriteLine("Document Read method for IStorable");
        }
        public void Write()
        {
            Console.WriteLine("Document Write method for IStorable");
        }
    }

    public class Note : Document
    { 
        public Note(string s) : base(s)
        {
           Console.WriteLine("creating Note with: {0}", s);
        }
        public override void Read()
        {
            Console.WriteLine("Overriding Read method for Note");
        }
        public void Write()
        {
            Console.WriteLine("My Write method for Note");
        }
    }


Why does isNote2.Write() print out the Document.Write() and not the Note.Write().

Since this is a object of type Note, which is casted to isNote2 which is a interface type, the resulting isNOte2.write() should implement the NOte.write() and not document.write().
Posted
Updated 19-Dec-11 15:07pm
v2

This is because you did not mark first method Write and virtual and the second one as override. If you did, it would work as you expected.

You also ignored compiler warning which told you that Node.Write hides the inherited method Write. If you did not ignore it, you would probably get the clue and understood the problem by yourself.

Now, I think you should get it. The problem itself is fixed, but do I have to explain you the behavior of the code you've shown in your question? It should be apparent from the above paragraph and the warning mentioned above.

[EDIT]

And do you really understand how dynamic dispatch via virtual mechanism and virtual method table really works? I hope you do. The presence of interfaces masks this picture a bit, but it makes no difference, in fact.

By the way, I would advise you do use explicit interface implementation syntax to reduce the chance of confusion. Consider changing the code to this:

C#
public class Document : IStorable
{
    public Document(string s) { /* ... */ }
    void IStorable.Read() { ImplementRead(); } //no access specifier allowed!
    void IStorable.Write() { ImplementWrite(); } //no access specifier allowed!
    internal protected virtual void ImplementRead() { /* ... */ }
    internal protected virtual void ImplementWrite() { /* ... */ }
}


Nothing is public, all is explicit, virtual methods are separated from interface implementations. There are some other benefits of explicit syntax.

—SA
 
Share this answer
 
v3
as a mater of fact since note.write() hides document.write(), the call to isnote2.write() should invoke the write method in the note class and not the document class....


Note note2 = new Note("Second Note");//this is a note object and not a document 
            IStorable isNote2 = note2 as IStorable;//casting 
 
            if (isNote2 != null)
            {
                isNote2.Read();
                isNote2.Write();//why does it not print as note2.write() but print as theNote.Write()?            
            }
 
Share this answer
 
v2
Thanks for your solution SAKryukov...I am totally new to C#...im from a C++ background....so im thinking that perspective...but I figured out the answer and would like to share with the rest who might stump into my difficulty...I also need the experts to comment on it...

Answer:

1)
C#
Note note2 = new Note("Second Note");

2)
C#
IStorable isNote2 = note2 as IStorable;//casting

3)
C#
if (isNote2 != null)
            {
                isNote2.Read();
                isNote2.Write();
             }




1) A Note object is created which by its nature has all the base class in it.
2) This casting makes a IStorable type refer to the Note object.
3) In the Read(), the IStorable type looks at the first derived class(the document class) and finds that method. However, since its virtual(and all the overheads of virtual look up)it finds the override method of Note type and prints that. It does the same for the Write() but since Write() is not virtual, it prints the document class. So casting causes the look up from top-down.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900