[Mono-devel-list] overriding return type

Alan Jenkins Alan.Jenkins at phonecoop.coop
Fri Jul 25 11:44:21 EDT 2003


Thanks for the reply.

I apologise for the (near) duplicate email I sent.  I thought the first one 
had not been sent.  Hopefully the moderator blocked it and saved me from my 
own stupidity.  Have been having unfortunate problems with email.

In the second email I changed some names and made the example slightly more 
complicated and less abstract by giving the objects state (int eg1.x, eg2.y), 
and having the method (clone()) return an object with the same state as the 
object it was invoked on.  Hope this is making sense.

C# does allow you to use implicit downcasts, only insisting on explicit 
upcasts.

//test.cs starts                                                                                                                 
//try it!                                                                                                                        
                                                                                                                                 
using System;                                                                                                                    
                                                                                                                                 
class ImplicitDownCast                                                                                                           
{                                                                                                                                
        public static void Main(String [] args)                                                                                  
        {                                                                                                                        
                example1 NewExampleObject;                                                                                       
                                                                                                                                 
                //explicit downcast                                                                                              
                NewExampleObject = (example1) new example2();                                                                    
                                                                                                                                 
                //implicit downcast                                                                                              
                NewExampleObject = new example2();                                                                               
                                                                                                                                 
                //explicit upcast - will throw cast exception                                                                    
                NewExampleObject = (example1) new object();                                                                      
                                                                                                                                 
                //implicit upcast - would not compile                                                                             
                //NewExampleObject = new object();                                                                               
        }                                                                                                                        
                                                                                                                                 
        class example1 {}                                                                                                        
        class example2 : example1{}                                                                                              
}                                                                                                                                
                                                                                                                                 
//EOF

When you talk about checking an example1 variable to see if it holds an 
example2 object, this is exactly what I wanted to avoid doing.  I want to be 
able to ensure (at compile time) that method() returns an instance of 
example2, not rely on a runtime check.

(I wish I'd stopped now.  I feel like the rest is a redundant rant, but don't 
like to kill it.  Feel free to stop reading now)


Here is an example which (i hope) illustrates more concretely what I would 
like to be able to do:


interface IList
{
	//get an iterator at the start of the list, i.e. before the first item
	IIterator Iterator();		
}

interface IIterator
{
	bool Next();		//move onto the next item, false on failure (EOL)
	object Item		//the current item
	{
		get;
		set;
	}		
}

interface IList2 : IList
{
	IIterator2 iterator();
}

interface IIterator2 : Iterator
{
	bool Prev();		//move onto the previous item, false on failure (SOL)
}

Without the ability to override the return type, I have to:

 - use differently named methods (Ilist2.Iterator2())
	Doesn't seem too bad... but leads to namespace pollution: what if I want to 
override the return type of a method more than once?  I get iterator(), 
iterator2(), iterator3()... , with all but the last method just applying a 
downcast to the result of the previous one)

- use a wrapper that emulates IIterator, passing everything onto an IIterator2 
instance, and wrap instead of casting
	Forget about inheritance and casting?  Why use OO at all?

- as you say, return a downcast value and require callers to upcast it
	And lose the ability to use interfaces to ensure classes provide a certain 
functionality

Chances are, you can do one of these things in a way which does not impose a 
performance cost, with the use of an intelligent compiler.  Put it down to 
arrogance: I like my way better :-).




More information about the Mono-devel-list mailing list