Activator Question

D

Dan Dorey

My goal is to pass in an assembly and have the method return an
instance of any classes that inherit from the generic type T.

My problem is that I'm unable to cast from the result of
Activator.CreateInstance(curType) to T even though curType is a
concrete class of T (T is abstract in this case). I'm unsure why I
can't make this cast. In another method where I don't have the
restriction of T being a class, this approch works fine when T is an
interface.

I kind of feel like I'm going about this the wrong way, so if anyone
has suggestions on a better approach, please let me know :)

Thanks,
Dan

public static List<T> GetClassesByClassName<T>(Assembly assembly,
object[] classParams) where T : class
{
List<T> ret = new List<T>();

foreach (Type curType in assembly.GetTypes())
{

if (InheritsFrom(curType, typeof(T)) &&
curType.IsAbstract == false)
{
if (classParams == null)
{

ret.Add((T)Activator.CreateInstance(curType));
}
else
{

ret.Add((T)Activator.CreateInstance(curType, classParams));
}
}
}

return ret;
}


private static bool InheritsFrom(Type curType, Type targetType)
{
bool ret = false;

while (curType.FullName != "System.Object")
{
if (curType.FullName == targetType.FullName)
{
ret = true;
break;
}
else
{
curType = curType.BaseType;
}
}

return ret;
}
 
A

AlanT

My goal is to pass in an assembly and have the method return an
instance of any classes that inherit from the generic type T.

My problem is that I'm unable to cast from the result of
Activator.CreateInstance(curType) to T even though curType is a
concrete class of T (T is abstract in this case). I'm unsure why I
can't make this cast. In another method where I don't have the
restriction of T being a class, this approch works fine when T is an
interface.

Not too sure if this counts as good news or bad news but the code as
written works fine for me

I created a few classes. (The base is abstract and I included a 2
level inheiritance just for fun)

public abstract class Widget {
private string _name;
public Widget(string name) {
_name = name;
}

public string Name {
get { return _name; }
}

}

public class MyWidget : Widget {
public MyWidget(string name) : base(name) { }
}

public class MySecondWidget : Widget {
public MySecondWidget(string name) : base(name) { }
}

public class MyThirdWidget : MyWidget {
public MyThirdWidget(string name) : base(name) { }
}


And then created a list of them with

Assembly assem = Assembly.GetAssembly(typeof (Widget));

List<Widget> list = NG.GetClassesByClassName<Widget>(assem,

new object[] {"A Name"});

I ended up with a list of 3 objects,

MyWidget,
MySecondWidget
MyThirdWidget

each initialized with "A Name".


All seems good. Are you getting a compile error or a runtime error?


NOTE:
You can replace InheritsFrom() with

typeof(T).IsAssignableFrom(curType)

e.g.
foreach (Type curType in assembly.GetTypes()) {
if (typeof(T).IsAssignableFrom(curType) &&
curType.IsAbstract == false) {
...


but I did that after testing the main functionality.

hth,
Alan.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top