On Tue, 01 Apr 2014 15:00:17 -0400, Frustrated <w...@where.com> wrote:
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().
There is no definition for B's vtable according to A. It just looks like
an array of void pointers.
In other words, there's no possible way, without knowing B's type
structure, to know which entry in the vtable is '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
Because you have (at runtime) determined that a actually IS a 'B'.
But the only problem is that the cast(B) is required and is a trick to
get the compiler to do what I want.
It's not a "trick", it's a runtime check. It basically is saying "if a is
actually a B, then call B.That, otherwise segfault"
But we know that a is of type B.
The compiler/runtime does not know that.
e.g., typeof(cast(Object)a) returns B, right?
You are thinking of typeid. But the runtime information does not contain
any way to figure out which location 'That' is at.
What you are really looking for is runtime introspection, similar to Java
or C#. D has the capability, but it has not been implemented. We only have
compile-time introspection.
I could be mistaken but isn't `A a = new B` just a facade and a really
is of type B?
a is of type A, and it points at an instance of 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?
You can get at B's typeinfo, but that doesn't contain a way to call
arbitrarily named functions.
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.
With the correct implementation of RTInfo inside object.di, you could
possibly make this work. It would be kind of cool. It would be a TON of
work to make this a reality.
-Steve