mardi 30 juin 2020

How to dynamically instantiate all fields of certain generic type?

I have a base type like this:

public class Group    {}

public class Group<T> : Group where T : class
{
    public Group()
    {
        InitAllGroupTypeInstances(this as T);
    }
}

And an instantiation method like this:

        public static void InitAllGroupTypeInstances<Thost>(Thost instance)
        {
            if (instance == null)
                return;

            var t = typeof(Group);
            while (true)
            {
                foreach (var Fi in typeof(Thost)
                    .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
                    .Where(fi => t.IsAssignableFrom(fi.FieldType)).ToList()) {
                    var n = Fi.Name;
                    if (Fi.FieldType != typeof(Type)) {
                        var it = (Group) Fi.GetValue(instance);
                        if (it == null) {
                            var Tgroup = typeof(Group<>);
                            Type[] typeArgs = {Fi.FieldType};
                            var Ttarget = Tgroup.MakeGenericType(typeArgs);
                            Fi.SetValue(instance, (Group) Activator.CreateInstance(Ttarget));
                        }
                    }
                }

                t = t.BaseType;
                if (t == null ||
                    t == typeof(Group)) {
                    break;
                }
            };
        }

I want to create an instance of something like this:

public class SimpleTwoHostNetwork : Group<SimpleTwoHostNetwork>
{
    public SimpleNetwork FromA, FromB;

    public SimpleTwoHostNetwork() : base() {}
}

public class SimpleNetwork : Group<SimpleNetwork> {
    public SimpleNetwork() {}
}

So that all the fields that are SimpleNetwork would construct themselves automagically. Yet I get an error like this:

enter image description here

System.ArgumentException: "Object of type 'ServicesPetriNet.Core.Group`1[ServicesPetriNet.Examples.SimpleTwoHostNetwork+SimpleNetwork]' cannot be converted to type 'ServicesPetriNet.Examples.SimpleTwoHostNetwork+SimpleNetwork'."

So I wonder what do I do wrong and how to dynamically instantiate all fields of certain generic type?





Aucun commentaire:

Enregistrer un commentaire