C# - 将泛型接口强制转换为传递运行时确定的类型 的泛型类

本文关键字:类型 泛型类 运行时 泛型接口 转换 | 更新日期: 2023-09-27 18:35:15

如何通过传递运行时确定的类型来强制转换具有泛型接口的泛型类?

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
}

我使用反射使用以下线程将运行时确定的类型传递给泛型类。但不知道如何将其转换为另一种泛型类型。

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
    }
}

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

你不能做IDataChangedService<T> .TSystem.Type 类型的运行时变量,而不是由字符串 typeName 表示的编译时类型。若要使用泛型参数,类型必须是编译时。

您需要引入一些非泛型类型来实现此工作。

像这样:

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
}

然后你可以做:

var obj = (IDataChangedService)Activator.CreateInstance(constructedClass);
obj.ProcessData(topic, subscription);