How do I create classes dynamically?

H. S. Teoh hsteoh at quickfur.ath.cx
Thu Apr 15 21:28:31 UTC 2021


On Thu, Apr 15, 2021 at 08:56:18PM +0000, mw via Digitalmars-d-learn wrote:
[...]
> of course, one can manually dispatch:
> 
> if      (userInputString == "cat") createCat();
> else if (userInputString == "dog") createDog();
> ...
> 
> but this this tedious.

-------------------
// Disclaimer: this is proof of concept, I didn't actually run this yet
class Animal {}
class Cat : Animal {}
class Dog : Animal {}

alias SupportedTypes = AliasSeq!(Cat, Dog, /* whatever else you want here */);

string userInputString = ...;
Animal result;
SW: switch (userInputString) {
	static foreach (T; SupportedTypes) {
		case T.stringof:
			result = new T;
			break SW;
	}
	default:
		throw new Exception("Unknown object type");
}
-------------------


> I have a similar question: how to dynamically use user's input string
> as function name can call it? suppose the function has no argument.

Same idea:

-------------------
// Disclaimer: this is proof of concept, I didn't actually run this yet
struct Dispatcher {
	void bark() { ... }
	void meow() { ... }
	void moo() { ... }
	... // whatever else you want here
}

Dispatcher disp;
string userInputString = ...;
SW: switch (userInputString) {
	static foreach (fieldName; __traits(allMembers, disp)) {
		static if (is(typeof(__traits(getMember, disp, fieldName))
			== function)
		{
			case fieldName:
				__traits(getMember, disp, fieldName)();
				break SW;
		}
	}
}
-------------------

Basically, the idea is to obtain a list of types/methods/whatever
somehow (either by explicitly listing instances, or via compile-time
introspection), then statically generate switch cases from it.  You can
eliminate many kinds of boilerplate using this little trick.


T

-- 
Береги платье снову, а здоровье смолоду. 


More information about the Digitalmars-d-learn mailing list