简体   繁体   English

C# - 将泛型接口转换为传递类型的泛型类 <T> 这是在运行时确定的

[英]C# - Cast generic interface to generic class that pass type <T> that is determined at runtime

How can I cast a generic class with generic interface by passing Type that is determined at runtime? 如何通过传递在运行时确定的Type来转换具有泛型接口的泛型类?

public class SomeDataChanged
    {
        public string EventName { get; set; }
    }

public class MessageSub<T> where T : class
{
    public IMessageBus Bus { get; set; }
    public ISubscription<T> Sub { get; set; }
}

public interface IDataChangedService<T> where T : class
{
    MessageSub<T> ProcessData(string topic, string subscription);
}

public class DataChangedService<T> : IDisposable, IDataChangedService<T> where T : class
{
    public MessageSub<T> ProcessData(string topic, string subscription)
    {
        // Some code
    }

    // More code
}

I have used reflection to pass type determined at runtime to the generic class using the following thread . 我使用反射将运行时确定的类型传递给使用以下线程的泛型类。 But not getting how to cast it to another generic type. 但是没有得到如何将它转换为另一种泛型类型。

class Test
{
    static void Main()
    {
        string topic = "OrderChanged";
        string subscription = "MyUi";
        string typeName = "OrderDataChanged";
        Type T = Type.GetType(typeName);

        Type genericClass = typeof(DataChangedService<>);
        Type constructedClass = genericClass.MakeGenericType(T);

        //How to cast another generic interface to my constructed class?
        var obj = (IDataChangedService<T>)Activator.CreateInstance(constructedClass); 

        //Also how to return generic type object?
        MessageSub<T> msgSub = obj.ProcessData(topic, subscription);

        // and, then some code that use msgSub
    }
}

You can't do IDataChangedService<T> . 你不能做IDataChangedService<T> The T is a run-time variable of type System.Type , and not a compile-time type represented by the string typeName . TSystem.Type类型的运行时变量,而不是字符串typeName表示的编译时类型。 To use generic parameters the type must be compile-time. 要使用泛型参数,类型必须是编译时。

You need to introduce some non-generic types to make this work. 您需要引入一些非泛型类型才能使其工作。

Something like this: 像这样的东西:

public interface IMessageSub { }

public class MessageSub<T> : IMessageSub where T : class
{
    public IMessageBus Bus { get; set; }
    public ISubscription<T> Sub { get; set; }
}

public interface IDataChangedService
{
    IMessageSub ProcessData(string topic, string subscription);
}

public interface IDataChangedService<T> : IDataChangedService where T : class
{
    MessageSub<T> ProcessData(string topic, string subscription);
}

public class DataChangedService<T> : IDataChangedService<T> where T : class
{
    IMessageSub IDataChangedService.ProcessData(string topic, string subscription)
    {
        return this.ProcessData(topic, subscription);
    }

    public MessageSub<T> ProcessData(string topic, string subscription)
    {
        // Some code
    }

    // More code
}

Then you can do: 然后你可以这样做:

var obj = (IDataChangedService)Activator.CreateInstance(constructedClass);

obj.ProcessData(topic, subscription);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM