tags:

views:

74

answers:

2

I have a base class "Element" and derived two other classes from it, "Solid" and "Fluid".

    class Element
    {...}

    class Solid : Element
    {
        public const int ElemType = 2;
        ...
    }

    class Fluid : Element
    {
        public const int ElemType = 3;
        ...
    }

I have made an instance of "Element" class, "E1". The following method is supposed to get an integer "ElType" and "E1" as its arguments and assign to "E1" as "Solid" or "Fluid" Element (or any other "Element" which will be introduced later). I mean, "E1" should be assigned to a "Solid" type if "IElType == 2" and "Fluid" type if "IElType == 3" and .... I wanted to make it possible for my colleagues to derive as many classes as they want, from "Element" class, and be sure that only by setting a proper value for "ElemType" the program will recognize their "Element"s.

    private static void ElemInitializer(int ElType, out Element E1)
    {
        E1 = new Element();
        Type T1 = typeof(Element);
        Type[] T2 = Assembly.GetAssembly(T1).GetTypes();
        List<Type> T3=new List<Type>();
        foreach (Type t1 in T2)
        {
            if (t1.IsSubclassOf(T1))
            {
                MemberInfo[] M1 = t1.GetMembers();
                foreach (MemberInfo m1 in M1)
                {
                    if (m1.Name == "ElemType")
                    {
                        FieldInfo F1 = t1.GetField("ElemType");
                        int int1 = (int)F1.GetValue(t1);
                        if (int1 == ElType)
                        {
                            // Here I want to assign to E1 as t1 type. Such as:
                            // E1 = new t1(); Of course this is wrong!
                        }
                    }
                }
            }
        }
    }

Here is the problem , I want "E1" be of type "t1", but it is not possible to do this by a simple code like this:

E1 = new t1(); //Of course this is wrong!

Is there any way to assign to "E1" as "t1" type? Sorry for nontechnical English.

A: 

Activator.CreateInstance(t1) should do the trick.

Niels van der Rest
+2  A: 

First of all, use a better naming convention, it makes it easier to help you and it will help your self in the long run too. The below code should do it

private static void ElemInitializer(int ElType, out Element E1)
{
    E1 = new Element();
    Type typeofElement = typeof(Element);
    Type[] assemblyTypes = Assembly.GetAssembly(T1).GetTypes();
    foreach (Type elementType in assemblyTypes )
    {
      if (elementType.IsSubclassOf(typeofElement))
      {
        FieldInfo field = elementType.GetField("ElemType");
        int elementId = (int)field.GetValue(elementType);
        if (elementId == ElType)
        {
           E1 = (Element)Activator.CreateInstance(elementType);
           return;
        }
      }
    }
}
Rune FS
I use visual studio 2005, with .NET 2.0. should I upgrade to later versions. because I can not find CreatInstanceOf method and by using CreateInstance I get the error of implicit conversion of object to Element.
There is no method named CreateInstanceOf. There's only Activator.CreateInstance().
Leniel Macaferi
no you don't need to update. I've corrected the error and removed the var's so that it should compile under 2.0 now. (The error you pointed out wouldn't compile in any version) I sadly do not have a compiler present I can test with but I think I got it right this time
Rune FS
I changed the code a bit since you don't need to iterate through alle the members (or fields) if you're just looking for one. I'm not testing for the returned FieldInfo beind differrent from null you might wanna do that
Rune FS