【问题标题】:Pass dynamically type to generic template将动态类型传递给通用模板
【发布时间】:2015-11-10 09:52:55
【问题描述】:

我遇到了 C# 中的反射问题。我需要构造一个用反射动态实例化类类型的泛型方法。我尝试的是以下内容。

Type myClass = Type.GetType(deviceBehavior.@class);
Type myInterfaceClass = myClass.GetInterface(deviceBehavior.@interface);

if (typeof (AnotherInterface).IsAssignableFrom(interfaceClass))
{
    CreateManager<interfaceClass>(serviceProvider, deviceCapability);
}

我的 CreateManager 方法如下:

private void CreateManager<T>(ServiceProvider serviceProvider, DeviceCapability deviceCapability)
{
    T instanceToCreate = CreateClass<T>(serviceProvider, deviceCapability);
    //Code to instantiate my class
}

问题是我不能打电话

CreateManager(serviceProvider, deviceCapability);

如何将接口传递给我的泛型类型?我搜索了,我找不到任何我能清楚理解的东西。即

Calling a static method on a generic type parameter

Pass An Instantiated System.Type as a Type Parameter for a Generic Class

【问题讨论】:

  • 抱歉,我无法理解您面临的问题是什么? “我不能打电话”到底是什么意思?
  • 我收到错误“找不到符号“interfaceClass”
  • stackoverflow.com/questions/2107845/… 我认为您的问题已经存在,但不是 100%,因为我不太喜欢仿制药

标签: c# generics reflection


【解决方案1】:

假设CreateManager&lt;T&gt;Foo 类型的方法:

public class Foo
{
    private void CreateManager<T>(ServiceProvider serviceProvider,
                                  DeviceCapability deviceCapability)
    {
    }
}

为了动态调用泛型方法,您需要先获取MethodInfo,然后使用您要传递的实际类型调用MakeGenericMethod(我选择string作为示例)

var foo = new Foo();
var createManagerMethod = foo.GetType()
                             .GetMethod("CreateManager", 
                                         BindingFlags.Instance | BindingFlags.NonPublic);

var method = createManagerMethod.MakeGenericMethod(typeof(string));
method.Invoke(foo, new object[] { new ServiceProvider(), new DeviceCapability() });

最后,使用正确的对象实例和参数调用Invoke

【讨论】:

  • 感谢您的回复。但是当我使用我的“类型对象”时,我得到了同样的错误“找不到符号”。我认为问题在于,通过这种方式,类型在编译器时被解析,而反射类型在运行时被解析。也许是这个?
  • 好的,效果很好!我用我的类型的 dinamyc 实例更改了字符串 typeof 并且它工作“MakeGenericMethod(new Type[] { interfaceClass })”
【解决方案2】:

我不明白,为什么您需要对此进行反思。你可以像下图那样做

public interface IYourInterface //Give it a good name
{
    void Instantiate(ServiceProvider serviceProvider, DeviceCapability deviceCapability);
}

public class YourClass : IYourInterface
{
    public YourClass() 
    {
        // do something if you want
    }

    public void Instantiate (ServiceProvider serviceProvider, DeviceCapability deviceCapability)
    {
       // what ever needs to be done here
    }
}

private void CreateManager<T>(ServiceProvider serviceProvider, DeviceCapability deviceCapability) 
    where T : IYourInterface, new()
{
    var instance = new T();
    instance.Instantiate(serviceProvider, deviceCapability);
}

/*
   Usage
*/

    CreateManager<YourClass>(serviceProvider, deviceCapability);

【讨论】:

  • 我需要反射,因为我从选项文件动态地读取类,然后我必须在运行时将它们添加到 serviceProvider。即 serviceProvider.Add(objectInstantiated);
  • 好的,在这种情况下,你不能那样做。 ;o)
  • 我终于做到了。你可以检查答案。感谢您的回复;)
  • 感谢您让我了解最新情况。很高兴听到你能成功。
猜你喜欢
  • 2014-05-20
  • 1970-01-01
  • 1970-01-01
  • 2020-08-05
  • 1970-01-01
  • 1970-01-01
  • 2016-10-01
  • 2017-12-25
  • 1970-01-01
相关资源
最近更新 更多