Instantiate a Class from Its Textual Name

Instantiate a class from its textual name

Here's what the method may look like:

private static object MagicallyCreateInstance(string className)
{
var assembly = Assembly.GetExecutingAssembly();

var type = assembly.GetTypes()
.First(t => t.Name == className);

return Activator.CreateInstance(type);
}

The code above assumes that:

  • you are looking for a class that is in the currently executing assembly (this can be adjusted - just change assembly to whatever you need)
  • there is exactly one class with the name you are looking for in that assembly
  • the class has a default constructor

Update:

Here's how to get all the classes that derive from a given class (and are defined in the same assembly):

private static IEnumerable<Type> GetDerivedTypesFor(Type baseType)
{
var assembly = Assembly.GetExecutingAssembly();

return assembly.GetTypes()
.Where(baseType.IsAssignableFrom)
.Where(t => baseType != t);
}

How do I instantiate a class given its string name?

Look at Activator.CreateInstance().

myObject = (MyAbstractClass)Activator.CreateInstance("AssemblyName", "TypeName");

or

var type = Type.GetType("MyFullyQualifiedTypeName");
var myObject = (MyAbstractClass)Activator.CreateInstance(type);

How to create an object of class from his string name?

Try this (providing MainClass has a default constructor):

  // Depending on where you call it, it may require full class name: "MyNameSpace.MainClass"
var b = Activator.CreateInstance(Type.GetType("MainClass"));

Cast object to actual class dynamically

You have at least two options for dynamic invocation of methods when the usual type-safe methods aren't applicable:

dynamic o = GetSomeObject();

o.SomeMethod();

or:

object o = GetSomeObject();
MethodInfo mi = o.GetType().GetMethod("SomeMethod");

mi.Invoke(o);

Note that the former is simpler and benefits from some compiler and run-time support (including caching of the dynamic binding) that doesn't occur in the latter example.

Call a class constructor dynamically in c#

You can use Activator class for the same

eg.

        Activator.CreateInstance<className>();

or

        Activator.CreateInstance(typeof(className));

Java - Does casting a variable to a type instantiate the type's class?

Wherever you would call the method getIndexPredicateTypeForArray from. You would pass a instance of ArrayType to this method as the only argument. That instance when created is responsible for calling the constructor of ArrayType or defining the fields declared within.l the class.

How to instantiate different classes depending on the type of a parameter?

A small remark first: I personally consider 'using namespace' a bad practice, because it ripples through header files. The reason is described throughout the internet.

Also, I always attempt to minimize using pointers, because of exception safety. Sutter has a nice book about it, called Exceptional C++, which describes these problems in a lot of detail. However, pointers obviously have their uses and one in particular is polymorphism. Lastly, I like making classes struct's if they only have public members... which is just a matter of taste.

Let's start with some code:

#include <string>
#include <iostream>
#include <memory>

struct Type
{
virtual void print() = 0;
};

struct Type1 : Type
{
void print() { std::cout << "I am of type 1" << std::endl; }
};

struct Type2 : Type
{
void print() { std::cout << "I am of type 2" << std::endl; }
};

class Action
{
protected:
std::unique_ptr<Type> t;
public:
Action(std::unique_ptr<Type> &&t) : t(std::move(t)) {};

void print()
{
std::cout << "I am an action. My type says: ";
t->print();
}
};

int main()
{
Action act(std::make_unique<Type1>());
act.print();

return 0;
}

The first problem you seem to address is the fact that user input generates the types. Depending on the input, this could point to an abstract factory or builder pattern or even a full-blown parser, but if it's an easy input decision, best to KISS:

int main()
{
std::string s;
std::getline(std::cin, s);

std::unique_ptr<Type> type;

if (s == "1")
{
type = std::make_unique<Type1>();
}
else
{
type = std::make_unique<Type2>();
}

Action act(std::move(type));
act.print();

return 0;
}

Usually you want to separate your model from the implementations though. Actions come in a lot of different shapes and forms, so you probably want to do something else depending on your model. A visitor pattern, double dispatch, or whatever you want to call it comes to the rescue here.

Note that I normally use a somewhat modified visitor, which returns the base type as a default. That way, you can easily incorporate transformations into your code, which imho is a common design requirement. At this point I'm just going to use pointers. Personally I'm a big fan of memory arena's to work around the issues of memory management, but I consider this out of scope for this answer.

To finish things off, a simple base class can help you get rid of the senseless plumbing.

struct TypeVisitor;

struct Type
{
virtual Type* Accept(TypeVisitor& visitor) = 0;
};

template <typename T>
struct TypeBase : Type
{
virtual Type* Accept(TypeVisitor& visitor) override
{
return visitor.Handle(static_cast<T*>(this));
}
};

struct Type1 : TypeBase<Type1>
{
};

struct Type2 : TypeBase<Type2>
{
};

struct TypeVisitor
{
virtual Type* Handle(Type1* input)
{
/* if necessary, recurse here like: input->child = input->child->Accept(this); */
return input;
}
virtual Type* Handle(Type2* input) { return input; }
};

struct DumpAction : TypeVisitor
{
virtual Type* Handle(Type1* input) override
{
std::cout << "Handling type 1." << std::endl;
return TypeVisitor::Handle(input);
}

virtual Type* Handle(Type2* input) override
{
std::cout << "Handling type 2." << std::endl;
return TypeVisitor::Handle(input);
}
};

int main()
{
DumpAction act;
Type2 type2;
type2.Accept(act);

return 0;
}


Related Topics



Leave a reply



Submit