www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Run-time reflection for class inheritance

reply Michael Green <abc.mikey gmail.com> writes:
I don't know if this would be a sensible approach to try and get 
at the actual class types for objects stored in some container at 
runtime?

I have noticed that this approach doesn't work if Event is an 
interface rather than a ancestor class.


```
import std.stdio;
import std.string;
import std.traits;
import std.conv;

interface Event {
	void report() {
		writeln("an event");
	}
}

class EventTimer : Event {
	override void report() {
		writeln("timer event");
	}
}

class EventSocket: Event {
	override void report() {
		writeln("socket event");
	}
}

void main(string[] args) {

	Event[] events;

	foreach (arg; args[1..$]) {
		// just something to pick actual type at runtime
		if (to!int(arg) > 5) {
			events ~= new EventTimer();
		} else {
			events ~= new EventSocket();
		}
	}

	foreach (event; events) {

		switch (event.classinfo.name) {
			case fullyQualifiedName!EventTimer:
				writeln("found timer event");
				break;
			case fullyQualifiedName!EventSocket:
				writeln("found socket event");
				break;
			default:
				throw new Exception("unknown event type");
				break;
		}

		event.report();
	}
}
```
Dec 01 2019
next sibling parent Michael Green <abc.mikey gmail.com> writes:
On Sunday, 1 December 2019 at 12:26:03 UTC, Michael Green wrote:
 interface Event {
[note to self - shouldn't make last minute checks and reverse them by hand before posting] That should of course read:
 class Event {
Dec 01 2019
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Sunday, 1 December 2019 at 12:26:03 UTC, Michael Green wrote:
 I don't know if this would be a sensible approach to try and 
 get at the actual class types for objects stored in some 
 container at runtime?
You can get the type at runtime by simply casting it... if(auto c = cast(EventSocket) event) { // is an event socket } and then you can actually use the c object too. Or if you put the necessary functionality in the interface then you simply call the method - this is better object-oriented design as it reduces the necessary knowledge for the function to use the object.
Dec 01 2019
parent Michael Green <abc.mikey gmail.com> writes:
On Sunday, 1 December 2019 at 14:42:46 UTC, Adam D. Ruppe wrote:
 You can get the type at runtime by simply casting it...

 if(auto c = cast(EventSocket) event) {
    // is an event socket
 }
Thanks. I guess you need to be careful about which order you do those tests so as not to cast to more general types before testing for specific ones. I also came up with ``` if (typeid(event) == typeid(EventTimer)) { // do something } ``` The reason I was leaning toward the first one is that it could be put in a switch as it's just string compares. I guess having it cast as part of the check is useful.
Dec 02 2019