Jump to content
  • Advertisement
Sign in to follow this  
iliak

[.net] Activator.CreateInstance as T

This topic is 3327 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi I'm scripting the monster in my game. Here's the interface for each monsters :
/// <summary>
/// Interface for monsters
/// </summary>
public interface IMonster
{
	void OnUpdate();

	void OnDraw();
}

An example for the RustMonster type. This source is loaded at runtime as a plain text (.cs) file and compiled on the fly. So I dont know it at compile time (the goal of scripting monsters...).
public class RustMonster : IMonster
{
	public void OnUpdate()
	{
		Trace.WriteLine("OnUpdate()");
	}

	public void OnDraw()
	{
		Trace.WriteLine("OnDraw()");
	}
}

I would like to create a new instance of RustMonster like this
	// Somewhere in my code
	IMonster rust = Script.CreateInstance<IMonster>("RustMonster");

CreateInstace definition
	public class Script
	{
		/// <summary>
		/// Creates an instance of T
		/// </summary>
		/// <typeparam name="T">Type of the instance</typeparam>
		/// <param name="name">Name of the class</param>
		/// <returns>An instance of or default(T)</returns>
		public T CreateInstance<T>(string name)
		{
			if (!IsCompiled)
			{
				Trace.WriteLine("Script \"" + Name + "\" is not compiled. Can't create a new instance \"" + name + "\" of type \"" + typeof(T).Name + "\"");
				return default(T);
			}

			// Get type
			Type t = CompiledAssembly.GetType(name, false);


			// Check interface
			if (t.GetInterface(typeof(T).Name) == null)
			{
				Trace.WriteLine("Type \"" + Name + "\" found, but not an instance of \"" + typeof(T).Name + "\".");
				return default(T);
			}

			// Create an instance
			var ret = Activator.CreateInstance(t);		// <--- Here is the problem
			return ret;
		}
	}

How can I "cast" the return as T ?

Share this post


Link to post
Share on other sites
Advertisement
Constrain will do the job, thank you !


public T CreateInstance<T>(string name) where T : class
{
if (!IsCompiled)
{
Trace.WriteLine("Script \"" + Name + "\" is not compiled. Can't create a new instance \"" + name + "\" of type \"" + typeof(T).Name + "\"");
return default(T);
}

// Get type
Type t = CompiledAssembly.GetType(name, false);
if (t == null)
{
Trace.WriteLine("Type \"" + Name + "\" found, but not an instance of \"" + typeof(T).Name + "\".");
return default(T);
}


// Check interface
if (t.GetInterface(typeof(T).Name) == null)
{
Trace.WriteLine("Type \"" + Name + "\" found, but not an instance of \"" + typeof(T).Name + "\".");
return default(T);
}


// Create an instance
return Activator.CreateInstance(t) as T;
}

Share this post


Link to post
Share on other sites
Just remember that "as T" won't throw an exception like it would if you just cast using "(T)" - instead, if the cast is invalid, it will just return null. Make sure this makes sense for your code.

Share this post


Link to post
Share on other sites
By the way, you might want to replace


if (t.GetInterface(typeof(T).Name) == null)

with

if (!typeof(T).IsAssignableFrom(t))


This is a safer way (not string based) to check whether t implements/derives from T.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!