www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Interface factory

reply luke <lukas.laedrach bluewin.ch> writes:
Hi everybody

I wrote the following code to be able to write unit tests for interfaces.

--------------------------------------------------------------
module test;

import std.stdio;

interface I
{
	void doSomething();
}

class Iimplementation : I
{
	void doSomething()
	{
		writefln("Hello world!");
	}
}

typedef I function() FactoryType;

Iimplementation Factory()
{
	return new Iimplementation();
}

void main()
{
	auto factory = &Factory;
	auto ifactory = cast(FactoryType)factory;

	I i = factory();
	i.doSomething();	// Prints 'Hello world!'

	i = ifactory();
	i.doSomething();	// Prints 'InterfaceClassTest.Iimplementation' <<< ??
}
--------------------------------------------------------------
compiled using dmd 1.015 on windows

The problem is marked in the source. When i create the instance using
factory the program works as expected, but when i cast it just prints
garbage(?).

Is this a normal behavior? If it is, how can i create an instance of
an interface using a factory?
Aug 14 2007
parent reply BCS <ao pathlink.com> writes:
Reply to luke,

 Hi everybody
 
 auto factory = &Factory;
 auto ifactory = cast(FactoryType)factory;

this is the issue here, an interface isn't quite the same as object reference. having a function that returns an object reference cast to a interface returning function doesn't work.
Aug 14 2007
parent reply luke <lukas.laedrach bluewin.ch> writes:
What about casting an interface to another?

Like:

interface A{}
interface B: A{}
class C : B{}

B Factory()
{
 return new C();
}


auto i = cast(A)Factory();

Could this work?
Aug 14 2007
parent reply BCS <ao pathlink.com> writes:
Reply to luke,

 What about casting an interface to another?
 
 Like:
 
 interface A{}
 interface B: A{}
 class C : B{}
 B Factory()
 {
 return new C();
 }
 auto i = cast(A)Factory();
 
 Could this work?
 

casting interfaces works fine, the compiler handles all the magic, however a function that returns the wrong type subverts this.
Aug 14 2007
parent reply luke <lukas.laedrach bluewin.ch> writes:
But i think the type should be valid because it implements the interface B.

Or am i wrong about the whole thing?
Aug 14 2007
parent BCS <ao pathlink.com> writes:
Reply to luke,

 But i think the type should be valid because it implements the
 interface B.
 
 Or am i wrong about the whole thing?
 

this code IS valid: interface A{} interface B: A{} class C : B{} B Factory() { return new C(); } auto i = cast(A)Factory(); Factory news a C, casts it to a B, and returns it then it is cast to an A and assigned. All OK the issue is when you coast a function returning an interface to a function returning another interface. When you do this the cast from the original type to the new type never happens, the reference is copied directly. However because of how interfaces are implemented this gives incorrect results. (The details were brought up in a thread about 4 or 5 days ago)
Aug 14 2007