www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Reference to implementation of interface.

reply "Christian Aistleitner" <xy7p3vxz gmx.net> writes:
Hello,

I am in need of a way to reference the class implementing an interface  
 from within the interface's definition.
Example:

interface A
{
   static A constA;
}

Here the type "A" within "static A constA" is short for any class  
implementing the interface "A". But I'd prefer to have some way to  
reference the class, which is implementing this interface -- and not "any  
class implementing A".

The above definition of the interface "A" allows to write

class B: A
{
   static B constA;
}

which is just what I want. However, it also allows

class C: A
{
   static B constA;
}

which I would like to forbid. The "B" within the "static B constA" is the  
problem. I would like to force it to "C" (the class currently implementing  
the interface "A") within the definition of the interface "A".

Can this be modelled with D?

Kind regards,
Christian Aistleitner
Jan 19 2007
parent reply Pragma <ericanderton yahoo.removeme.com> writes:
Christian Aistleitner wrote:
 Hello,
 
 I am in need of a way to reference the class implementing an interface 
 from within the interface's definition.

Offhand, I'd say the best way to do that is with a templated base-class or interface. For example: interface Bar(T){ static T baz; // in the class below, 'baz' will by of type 'Foo' } class Foo: Bar!(Foo){ } -- - EricAnderton at yahoo
Jan 19 2007
parent reply "Christian Aistleitner" <xy7p3vxz gmx.net> writes:
Hello,

On Fri, 19 Jan 2007 22:41:55 +0100, Pragma  
<ericanderton yahoo.removeme.com> wrote:

 Christian Aistleitner wrote:
 Hello,
  I am in need of a way to reference the class implementing an interface  
 from within the interface's definition.

Offhand, I'd say the best way to do that is with a templated base-class or interface. For example: interface Bar(T){ static T baz; // in the class below, 'baz' will by of type 'Foo' } class Foo: Bar!(Foo){ }

although I see that your code allows to model the problem, its actually artificial and rather cumbersome to pass the implementing class as a parameter, wherever I'd need such an operator. And the knowledge that the parameter Foo has to match the class' name is implicit by the design and cannot be checked by the compiler. Kind regards, Christian
Jan 20 2007
parent Pragma <ericanderton yahoo.removeme.com> writes:
Christian Aistleitner wrote:
 Hello,
 
 On Fri, 19 Jan 2007 22:41:55 +0100, Pragma 
 <ericanderton yahoo.removeme.com> wrote:
 
 Christian Aistleitner wrote:
 Hello,
  I am in need of a way to reference the class implementing an 
 interface from within the interface's definition.

Offhand, I'd say the best way to do that is with a templated base-class or interface. For example: interface Bar(T){ static T baz; // in the class below, 'baz' will by of type 'Foo' } class Foo: Bar!(Foo){ }

although I see that your code allows to model the problem, its actually artificial and rather cumbersome to pass the implementing class as a parameter, wherever I'd need such an operator. And the knowledge that the parameter Foo has to match the class' name is implicit by the design and cannot be checked by the compiler.

I agree, there's a certain lack of type protection to the whole thing, and it is a little cumbersome. It can be improved by narrowing what T can be: private interface IBar{} interface Bar(T: _Bar) : IBar{ } ...which ensures that any T must also be castable to type "IBar" (and hence "Bar" provided nothing else uses "IBar"). That's at least some protection from a developer using a bogus argument. However, this is pretty much the only way to solve this particular problem. Simply put: there is no way an interface (or a class for that matter) can deduce it's implementing type (or descendant) at compile time without an explicit hint like this. The only construct that D offers for type deduction at compile time, aside from templates and "auto", is "typeof(this)". However, that only gives you the enclosing type - so you could only get 'Bar' within 'Bar' and 'Foo' within 'Foo'. -- - EricAnderton at yahoo
Jan 22 2007