将基类型转换/强制转换为派生泛型类型

本文关键字:转换 派生 泛型类型 类型转换 | 更新日期: 2023-09-27 18:22:48

在下面的代码中,我想调用一个在派生类中声明的方法:

class BaseClass
{
    // ...
}
class A<T> : BaseClass
{
    public void F(T args){ //... }
}
class B<T> : BaseClass
{
    // B<T> doesn't have method F()
}
///....
class myApplication
{
    // ...
    public void DoSomething(BaseClass arg)
    {
        // Now I know that arg is of type A<T> for some type T
        // but I don't know what T is. Also declaring DoSomething
        // as DoSomething<T>() is not an option.
        // 
        // I would like to call (arg as A<T>).F(...) but how can I
        // deduce T? Can it be done in any other way?
    }
}

请阅读代码中的注释。我怎么能做这样的事?

将基类型转换/强制转换为派生泛型类型

为了调用该方法,您可以运行以下代码:

class myApplication
{
    // ...
    public void DoSomething(BaseClass arg)
    {
        var type = arg.GetType();
        // Check whether a generic type was passed
        if (type.IsGenericType)
        {
            var genType = type.GetGenericTypeDefinition();
            // Check whether it is of type A<>
            if (genType == typeof(A<>))
            {
                // Get generic argument type
                var genArg = type.GenericTypeArguments[0];
                // Create a default instance; might not work under all circumstances
                // Better to get the method parameter in another way
                var mthArg = Activator.CreateInstance(genArg);
                // Get method that is to be called
                var mth = type.GetMethod("F");
                // Invoke method dynamically
                mth.Invoke(arg, new object[] { mthArg });
            }
        }
    }
}

请注意,将类型为T的参数传递给方法F非常重要。你必须为此准备好价值。在我的示例中,我添加了对Activator.CreateInstance的调用,该调用要求T具有公共默认构造函数(我使用int进行测试)。