-2

I want to create objects dynamically by String, but struggle with this piece of code:

using System;
using System.Reflection;

namespace simple.test.project {

    public class Dog {
        public string Sound { get; set; } = "woof woof";
    }

    public class Animal<T> where T : new() {
        public T GetInstance() {
            return new T();
        }
    }


    class MainClass {


        public static void Main(string[] args) {

            var a = Assembly.GetExecutingAssembly().CreateInstance("simple.test.project.Dog");
            Type t_a = a.GetType();

            var a_t = typeof(Animal<>);
            var g_a_t = a_t.MakeGenericType(t_a);
            var o = Activator.CreateInstance(g_a_t);

            var dog = o.GetInstance() // object does not contain... message

        }
    }
}

The last statement var dog= will not be accepted by the compiler because GetInstance would not be known. How the code has to be looks like to get it work?

Sam Axe
  • 33,313
  • 9
  • 55
  • 89
frameworker
  • 298
  • 1
  • 3
  • 16
  • var dog = (Dog)o.GetInstance(). Get instance only returns an object, you need to assume its the correct type first cast the object to Dog – johnny 5 Oct 16 '19 at 21:31
  • 3
    as your type is only known at **runtime**, there's no way for the **Compiler** to infer that type. And thus it has absolutely no idea what o.GetInstance returns, all you get is just object. Anyway you won't need any GetInstance at all. Just use what Activator.CreateInstance returns and cast that to Dog – MakePeaceGreatAgain Oct 16 '19 at 21:32
  • 1
    Your animal-class should not be generic at all. Instead just make your Dog inherit Animal. – MakePeaceGreatAgain Oct 16 '19 at 21:37
  • 1
    Once you start down the path of accessing types and instances dynamically, i.e. via reflection, you are stuck with that until you are willing to cast the dynamically-retrieved results back to a statically (compile-time) known type. In the meantime, reflection and expressions are the mechanisms you'll need to use. See marked duplicate for information on calling a named method via reflection. – Peter Duniho Oct 16 '19 at 21:46

1 Answers1

-2

Let's use Activator.CreateInstance(Type).

public class Dog
{
    public string Sound { get; set; } = "woof woof";
}

class Program
{
    static void Main(string[] args)
    {
        var dog = (Dog)Activator.CreateInstance(typeof(Dog));

        Console.WriteLine(dog.Sound);
        dog.Sound = "Homeowner".Substring(2, 4);
        Console.WriteLine(dog.Sound);
    }
}

Output

woof woof
meow

Version with strings

public class Dog
{
    public string Sound { get; set; } = "woof woof";
}

public class Dog
{
    public string Sound { get; set; } = "woof woof";
}

class Program
{
    static void Main(string[] args)
    {
        var dog2 = Activator.CreateInstance(Type.GetType("Dog"));

        Console.WriteLine(dog2.GetType().GetProperty("Sound").GetValue(dog2, null));
        dog2.GetType().GetProperty("Sound").SetValue(dog2, "Homeowner".Substring(2, 4));
        Console.WriteLine(((Dog)dog2).Sound);
    }
}
tymtam
  • 31,798
  • 8
  • 86
  • 126