Can I set the type of a field within a class at runtime to a newly created type in c#?

216 Views Asked by At

I'm using Reflection.Emit and TypeBuilder to create a new type at runtime. My setup is something like:

public class MyClass {
    public object MyField = CreateInstanceOfNewType();
    public MyClass() {}
}

The issue is that MyClass.MyField is declared with type object and so the implicit cast operators that exist for the new type are not called when castable types are assigned to MyClass.MyField. Is there a way to set the type of the field to the newly created type so that it behaves similarly to how it would in the typical case?

2

There are 2 best solutions below

0
On

If I've understood correctly, you want to initialize an object of your new type with an object of some castable type you've built an implicit cast operator for. I would suggest that instead of implicit operators you consider using constructors: use Reflection.Emit to create constructors that take one parameter of your castable types and use that parameter value to initialize the object of the new type. You want to have same result as this piece of code would do:

public class MyNewType
{
    public MyNewType(CastableType value)
    {
        /* implement initialization with value */
    }

    /* other stuff */
}

You can then use Activator.CreateInstance(Type type, params object[] arguments) to make use of that constructor. Here's an example:

var newType = GetNewType();
var castableObject = CreateInstanceOfCastableType();
this.MyField = Activator.CreateInstance(newType, castableObject);
2
On

This depends on the exact use case, a possible solution is to make your class generic, then use reflection to create a static generic method that creates an instance of the class. This allows you to use the variable dynamic type when declaring your property:

public class MyClass<T> { 
public T MyField = CreateInstanceOfNewType<T≥(); 
public MyClass() {} 
}

public static MyClass<T> createClass<T>() {
return new MyClass<T>:
}

dynamic instanceOfMyClass = typeof(SomeClass).GetMethod("createClass").MakeGeneric(dynamicType).Invoke()

Another alternative is using the dynamic keyword.