[Mono-devel-list] overriding return type
Alan Jenkins
Alan.Jenkins at phonecoop.coop
Sat Jul 26 11:06:46 EDT 2003
I totally agree that neither of us are OO experts, and I'd like to add that
I've not exactly been an expert communicator either. Thanks for taking the
time to disagree with me, especially as you've done all the code in your
head.
5,000 .cs files, you say! Thats a lot of code. I didn't mean to imply that
the class library would be written or compiled using this feature -
implementing a compatable clone of a class library must be hard enough
without having to use a slightly different language to the original. Mono
might strike off in its own direction at some point, but diverging from MS
.NET is not a good idea at the moment. Leave that for later, when Mono has
become the standard implementation of .NET (smile, but don't laugh - look at
GNU/Linux and Unix). Thats why I didn't say "please consider adding this
feature in the next version" - I am interested in it mainly for selfish
reasons, and it could well break the ECMA standard.
I accept that any idea like this is potentially dangerous, and must be
examined carefully - but thats one of the reasons why it would be an
extremely good idea to make it an optional feature. I don't think there are
(bad) implications which would only become obvious with multiple derivatives,
and the additional complexity caused by extra derivative classes would not
become execessive.
I agree that there must be a reason why this feature is not present in the C#
(and Java) compiler, even though CIL does support it. I've done some
serching on the web, and I think C++ will let you do this, but thats not
saying much (what doesn't C++ let you do?):
//test.cpp - compiles sucessfully on my computer.
int main() { }
class Example1 {
virtual Example1 *Method() {
return new Example1();
}
};
class B : public A {
virtual Example2 *Method() {
return new Example2();
}
};
//test.cpp ends
---
Could you please clarify some of your comments?
>> // This works because IList2 implements IList
>> IList list = GetList.NewList();
don't you mean "because IList3 implements IList"?
>> // This causes a casting error because our list is an IList3
>> // and its Iterator() method returns an IIterator3 object. The
>> // correct thing is for Iterator to return an IIterator object, and
>> // check to see if it can be upcast to IIterator2
>> IIterator2 iterator2 = list.Iterator();
Did you mean a runtime or a compile time error? I assume you mean a runtime
error, from the way you put it, and from your other comments.
I would have thought you would get a compile time error, because what you are
doing is implicitly upcasting IIterator to IIterator2.
I think I understand the detail of your example, but not the reason for coding
it this way.
Your last line implicitly assumes that the return value of GetList.New() is an
IList2 - thats why it fails. Surely its better to express this assumption
explicitly:
//results in compile time cast error: implicit upcast
IList2 list = GetList.NewList();
//results in runtime error: explicit upcast failure
IList2 list = (IList2) GetList.NewList();
Neither do I understand why GetList.NewList() has a return type of IList, when
it always returns an object of type IList3. I would have thought that it
would have made more sense to give it a return type of IList3, so that it was
both obvious and certain that it would return an IList3 object.
GetList.NewList() doesn't return a suitable list for the operations performed
on it - NewList(), and/or the code using it is flawed. You assert that the
correct fix is to change the return type of IList2.Iterator() and
IList3.Iterator() to IIterator, and for calling code to upcast the result.
Essentially, you remove the strict obligation on implementors of
IList2.Iterator() and IList3.Iterator() to return an appropriate iterator,
and presumably make the obligation known through comments or attributes.
Surely this is more error prone, not less, just as the requirement in Java to
explicity define the exceptions thrown by specific methods eases development
(esp. debugging).
The assumptions made by the calling code are expressed (as far as I can see)
in such a way as to cause a compile time error. I understand that if similar
assumptions caused runtime errors they could be difficult to fix, but I think
it would be fairly easy to avoid them altogether. I would have thought that
your solution is more likely to result in runtime errors (when explicitly
upcasting the return value of a method), whereas if you can override return
types, you are more likely to catch the errors at compile time (implicit
upcasts).
More information about the Mono-devel-list
mailing list