Covariant return type
Chris Nicholson-Sauls
ibisbasenji at gmail.com
Thu Mar 22 12:25:43 PDT 2007
Aarti_pl wrote:
>
>
> Jarrett Billingsley napisał(a):
>> "Aarti_pl" <aarti at interia.pl> wrote in message
>> news:ettjqu$14jb$1 at digitalmars.com...
>>> Hello!
>>>
>>> Shouldn't code below work?:
>>>
>>> //-------------------------------------------
>>>
>>> abstract class Storage {
>>> Storage get() {
>>> return this;
>>> }
>>> }
>>>
>>> class SpecificStorage : Storage {
>>> void print() {}
>>> }
>>>
>>> void main() {
>>> SpecificStorage s = (new SpecificStorage).get();
>>> s.print;
>>> }
>>>
>>> //-------------------------------------------
>>>
>>> Unfortunately currently you have to add overridden implementation of
>>> get() in SpecificStorage, like below (what is a little bit tedious
>>> work):
>>>
>>> SpecificStorage get() {
>>> return this;
>>> }
>>>
>>>
>>> But my intuition about that would be that "this" pointer from method
>>> get from Storage class will point to "SpecificStorage" when there is
>>> instantiated SpecificStorage. But it looks that in fact this points
>>> to "Storage".
>>
>> Sounds like it's behaving correctly to me. When you call .get on a
>> SpecificStorage, the only override of it is the one that returns a
>> Storage in the base class, and you can't cast from Storage to
>> SpecificStorage implicitly. The language will not implicitly define
>> covariantly returning versions of your methods for you; that's up to you.
>>
>
> Yes, but in fact I don't want to loose type information and upcast to
> Storage. I just want to return 'this' as it is when return is invoked.
>
> Such a behavior seems a little bit nonsense when there is covariance
> return type feature in programming language. To get covariance I have
> many time reimplement same code in every inherited class just to trigger
> proper behaviour.
>
> I think that it should not break anything when instead of making
> upcasting during return compiler just return concreate type and probably
> later make upcast when e.g. assigning to Storage variable. It should
> also not break visibility as I return SpecificStorage - If I would want
> to return Storage I can make upcast before return even in base class:
>
> Storage get() {
> return cast(Storage)this;
> }
>
> ....
>
> But maybe I am wrong... Do you think it would be enhancement for
> language to have something like this? Or it can break something?...
>
> I get to this problem with few simple, guarded setters methods in base
> class, which should return 'this' to achieve chaining. They should
> behave exactly same in all derived classes and currently the only way is
> to copy slightly modified implementation to derived classes...
>
> If you think it could be useful I will fill enhancement on bugzilla...
> Or maybe it should be putted for discussion to main D forum? (as it
> doesn't look like error according to answer)...
>
> BR
> Marcin Kuszczak
> (aarti_pl)
In full truth, the type information is not completely lost.
SpecificStorage s = cast(SpecificStorage)( (new SpeceficStorage).get() );
Or, something more likely to be found:
SpecificStorage s;
if (auto ref = cast(SpecificStorage)( someObj.foo() )) {
s = ref;
}
else {
throw new Exception(...);
}
And when the new D comes to us...
macro Blarg (cls, var, expr, msg) {
cls var;
if (auto ref = cast(cls)( expr )) {
var = ref;
}
else {
throw new Exception(msg);
}
}
// and in code...
Blarg(SpecificStorage , s, someObj.foo(), "...");
Blarg(AlternativeStorage, a, someObj.bar(), "...");
Assuming I understand the upcoming macros right... Which if I do, I can't wait for this.
-- Chris Nicholson-Sauls
More information about the Digitalmars-d-learn
mailing list