C# 为变量声明和赋值使用动态生成的类型

C# 为变量声明和赋值使用动态生成的类型,c#,generics,C#,Generics,在下面的问题中,可以像这样动态创建类型和实例表单: var type = typeof(AnimalContext<>).MakeGenericType(a.GetType()); var a_Context = Activator.CreateInstance(type); private int HandleInstance(Type itemType, //other args) { if (itemType == Type.type1) { t

在下面的问题中,可以像这样动态创建类型和实例表单:

var type = typeof(AnimalContext<>).MakeGenericType(a.GetType());
var a_Context = Activator.CreateInstance(type);   
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
{
// 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!");
}
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();
    }
}
// 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!
但是我不能将创建的类型(
var type=typeof(AnimalContext).MakeGenericType(a.GetType());
用于声明。这可能吗

编辑

出现需求的简短场景说明。我需要调用一个将从“topManager”调用的方法,此topManager持有实现相同基本接口的类型
type1Manager
type2Manager
的各自实例
IMyInterface
方法
ImplementedMethod

我想做的事情,可以用
if
s解决,如下所示:

var type = typeof(AnimalContext<>).MakeGenericType(a.GetType());
var a_Context = Activator.CreateInstance(type);   
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
{
// 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!");
}
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();
    }
}
// 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!
但是,我想知道是否可以通过处理类型来避免使用
if
s来解决这个问题,比如(用来找出问题关键的大写字母,而不是大声喊叫):

private int HandleInstance(类型itemType,//其他参数){
类型managerType=itemType==Type.type1?类型(managerType):
typeof(manager2Type);
Type[]managerTypeArray={managerType,typeof(int)};
var myDynamicallyCreatedType=typeof(IMyInterface);
//问题的关键。这就是我要问的
//将创建的变量分配给动态创建的类型以调用相应的方法
myDynamicallyCreatedType variableName=topManagerInstance.type1Manager;
//基本类型。任何要分配的type1ManagerType或type2ManagerType,如
//它们继承自同一IMyInterface,创建的类型为
//一般的
variableName.ImplementedMethod(//args):
}

看起来您只是想将枚举值映射到特定实现中的函数调用。一种方法是让一个工厂类使用字典作为映射来处理它。例如:

给定如下设置:

var type = typeof(AnimalContext<>).MakeGenericType(a.GetType());
var a_Context = Activator.CreateInstance(type);   
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
{
// 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!");
}
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();
    }
}
// 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!
现在你可以有一个这样的工厂:

var type = typeof(AnimalContext<>).MakeGenericType(a.GetType());
var a_Context = Activator.CreateInstance(type);   
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
{
// 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!");
}
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();
    }
}
// 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!

你不能,因为它没有意义…
myDynamicallyCreatedType
将在运行时而不是编译时知道。我真的不清楚你想在这里实现什么。通常当我看到有人试图像这样动态创建类型时,这是一种代码味道,但没有任何上下文,很难说。@Selvin我明白了,谢谢你的提醒我检查了名称空间,似乎不太可能,但无法基于动态创建的类型进行变量赋值?如
Activator.CreateInstance(type);
,类似于
Activator.Assign()
?您的
a_上下文
是一个对象。您唯一的机会就是转换到所需的类型:
列出a_上下文_类型=(列出)a_上下文;
。但是,您必须在编译时知道它是什么类型。您可以使用接口和逆变/协方差(取决于需要)这似乎正是我一直在寻找的。我稍后会尝试一下,并让您知道它是否符合我的需要。情况是,这涉及到另一层复杂性,因为我的界面具有泛型,
Foo
Bar
是确定类型的特定实现。更好地解释了。谢谢谢谢你的帮助!!