0

Following this question, it is possible to create a type and an instance form it dynamically like this:

var type = typeof(AnimalContext<>).MakeGenericType(a.GetType());
var a_Context = Activator.CreateInstance(type);   

Great.

However, what I want to do instead of creating an instance of a determined type with Activator.CreateInstance(type);is to use a dynamic created type to declare a variable, and assign an instance to my dynamically created type.

Kind of:

myDynamicallyCreatedType variableName = figuredTypeInstace;

But I cannot use the created type(var type = typeof(AnimalContext<>).MakeGenericType(a.GetType()); for declarations. Is that possible?

Edit:

Short scenario explanation where the need came up. I need to call a method that will be called from a "topManager", this topManager holds the respective instance of the types type1Manager and type2Manager that implement the same base interface IMyInterface method ImplementedMethod.

What I am trying to do, could be solved with ifs, like this:

private int HandleInstance(Type itemType, //other args) {
    if (itemType == Type.type1) { 
       topManagerInstance.manager1Instance.ImplementedMethod(//args):
    }
    elseif (itemType == Type.type2) { 
       topManagerInstance.manager2Instance.ImplementedMethod(//args):
    }
    ...not meaningful code
{

But, I was wondering if it could be solved handling types to avoid the ifs, like (caps used to spot the key of the question out, not to shout):

private int HandleInstance(Type itemType, //other args) {
    Type managerType = itemType == Type.type1 ? typeof(manager1Type) : 
    typeof(manager2Type);
    Type[] managerTypeArray = { managerType, typeof(int) };
    var myDynamicallyCreatedType = typeof(IMyInterface<,>).MakeGenericType(managerTypeArray);

    //KEY OF THE QUESTION. THIS IS WHAT I AM ASKING FOR
    //assign created variable to dynamic created type to call respective method
    myDynamicallyCreatedType variableName = topManagerInstance.type1Manager; 
    //base type. any type1ManagerType or type2ManagerType to be assigned, as 
    //they inherit from the same IMyInterface<,>, and the type created is 
    //generic
    variableName.ImplementedMethod(//args):
}
rustyBucketBay
  • 4,320
  • 3
  • 17
  • 47
  • 2
    you cannot as it doesn't make sens ... `myDynamicallyCreatedType` would be know on runtime not compile time – Selvin Mar 22 '21 at 10:50
  • I'm really not clear on what you are trying to achieve here. Usually when I see someone trying to create types dynamically like this, it's a code smell, but without any context, it's hard to tell. – DavidG Mar 22 '21 at 10:59
  • @Selvin I see, thanks for your comment. I checked in the namespace and it does not seem to be a chance, but there is no way to do a variable assignment based on a dynamically created type? as in the `Activator.CreateInstance(type);`, kind of `Activator.Assign();`? – rustyBucketBay Mar 22 '21 at 11:01
  • Your `a_Context` is an object. The only chance you have is to cast to your desired type: `List a_Context_Typed = (List) a_Context;`. But again, you'll have to know at compile time what type it is. – SomeBody Mar 22 '21 at 11:01
  • you can use interfaces and contravariance/covariance(depends on needs) [like this](https://dotnetfiddle.net/ulNuVq) – Selvin Mar 22 '21 at 11:04
  • thanks, thats so cool, but I dont want to create an instance, my instance is already created. I will edil the question to explain my scenario that is not that complex I think – rustyBucketBay Mar 22 '21 at 11:09
  • I feel like you're overthinking this. Could you use something like this instead? https://dotnetfiddle.net/juNsaN – DavidG Mar 22 '21 at 11:38
  • thanks a lot for your proposal, I think it is almost as you propose, but instead of creating a new instance `var x = new T();` in the call method, I want to call the `SomeMethod` from an instance that is already created. In my sample proposal I have access to both of the manager intances through the `topManagerInstance`. The point would be to call the `type1Manager.SomeMethod` or the `type2Manager.SomeMethod` depending on the type received as an argument...or call the respective implementation, but from the already created instance, not creating a new one – rustyBucketBay Mar 22 '21 at 12:31
  • The point of all this question is if based on an enum argument, I can call the respective instance impplemention of a method avoiding the obvious `if (enumValue == argumentEnumValue )` then call the respective instance implementation. I think that I might be misusing the dynamic type creation if this is not possible and might be overthinking this after all, however I find he question fair to understand the usage cases and limits of dynamic type creation – rustyBucketBay Mar 22 '21 at 12:37

1 Answers1

1

It seems like you're just looking to map an enum value to a function call in a specific implementation. One way to do that is to have a factory class that handles it with a Dictionary used as a map. For example:

Given a setup something like this:

// The enum you use for mapping
public enum Thing
{
    Foo,
    Bar
}

// The various implementations...
public interface ISomeInterface
{
    void SomeMethod();
}

public class Foo : ISomeInterface
{
    public void SomeMethod() => Console.WriteLine("Foo method!");
}

public class Bar : ISomeInterface
{
    public void SomeMethod() => Console.WriteLine("Bar method!");
}

Now you could have a factory that looks like this:

public class MyThingFactory
{
    private Dictionary<Thing, ISomeInterface> _registry;
    
    public MyThingFactory()
    {
        _registry = new Dictionary<Thing, ISomeInterface>
        {
            {Thing.Foo, new Foo()},
            {Thing.Bar, new Bar()},
        };
    }
    
    public void RunMethod(Thing thing)
    {
        if(!_registry.TryGetValue(thing, out var item)) 
        {
            throw new ArgumentOutOfRangeException(nameof(thing));
        }
        
        item.SomeMethod();
    }
}

And call it like this:

// You may want to make this static for performance reasons since you won't recreate
// the dictionary every time
var factory = new MyThingFactory();

factory.RunMethod(Thing.Foo);
factory.RunMethod(Thing.Bar);

//Output:
//Foo method!
//Bar method!
DavidG
  • 113,891
  • 12
  • 217
  • 223
  • that seems very much what I was looking for. I will give it a try later on and let you know if it works – rustyBucketBay Mar 22 '21 at 13:08
  • Seem to be what I would need. The case is that there is another layer of complecity involved, as my interface has generi cs, and `Foo` and `Bar` are specific implementations for determined types. Better explained [here](https://stackoverflow.com/questions/66750352/use-an-interface-type-with-generics-as-container-type-to-map-intances-of-the-imp). Thanks a lot for your help!! – rustyBucketBay Mar 22 '21 at 16:48