On Tuesday, 1 April 2014 at 12:20:06 UTC, Steven Schveighoffer
wrote:
On Tue, 01 Apr 2014 03:31:41 -0400, Frustrated <w...@where.com>
wrote:
Basically in programming to interfaces I need to decide to
call a virtual method of an object if it exists else call a
final method in the interface:
interface A
{
static final void foo() { ... }
}
class B : A
{
void bar() { ... } // optional
}
class C : B
{
void bar() { ... } // optional
}
void main()
{
A a = new B; // or new C;
// if a.bar exists call it, else call foo
// code should work independent of the classes. (there
might be more)
}
The point of the code is simply to allow the class to
implement bar optionally but provide default behavior with
foo. I need a way to dynamically determine if bar exists and
fall back on foo. This should be possible.
e.g., suppose
class B : A { }
then I would like to b.bar() to actually call A.foo() (since
bar doesn't exist in b).
I guess the exist way would be to create an opDispatch and
have it call foo if bar is passed. This works great and does
everything I need it to except requires adding the code in the
class which I can't have. Also I'm not sure how it would work
with virtual methods.
Detecting whether bar exists can only happen at compile time,
since an instance of A has no mechanism to detect whether it
has bar. D does not have very good runtime introspection, that
would have to be built into the TypeInfo struct (the mechanism
exists to do it, but it has never been used for that).
You could use this templates, but that would only work if the
type of the derived class is known at compile time.
This problem could easily be solved by virtual methods with
default implementation.
-Steve
It seems logical to me that I should be able to achieve what I
what.
Suppose I have an object cast to it's interface:
A a = new B;
when I call a.This() it will call the method in the interface.
Either This is a virtual method or a final method. Suppose it is
a Final method since if it is virtual there is no problem.
Now suppose B implements That as a virtual method that doesn't
exist in A.
Since a IS a B, That exists in it's vtable. I should be able to
call it:
a.That(); // Calls B's That().
Of course this doesn't work directly because That() is not part
of the interface. Regardless though, it still exists:
(cast(B)a).That(); // Works
But the only problem is that the cast(B) is required and is a
trick to get the compiler to do what I want.
But we know that a is of type B.
e.g., typeof(cast(Object)a) returns B, right?
Basically, it should be very easy for the compiler to internally
cast a object to it's actual type(since that is contained in the
object information, even if it's cast to something else) and call
members on it. Of course, I'm not asking for an internal way.
I could be mistaken but isn't `A a = new B` just a facade and a
really is of type B? If so, isn't there a way to get the true
type of a at runtime? If so, then can't we cast a to its true
type at runtime and access its members properly?
e.g., suppose truecast(a) returns a as the actual object that a
was created as(in this case B, not A). Then truecast(a).That()
would work.
I'm sort of looking for the truecast function/template.
Of course, if D doesn't store information about the actual type
an object is inside it(which it doesn't AFAIK) then you can't
truecast.