Generics 强制转换运行时创建的泛型类型

Generics 强制转换运行时创建的泛型类型,generics,casting,c++-cli,Generics,Casting,C++ Cli,我想创建一个在运行时创建的泛型类来转换泛型类型。下面的版本应该在实例化后将double转换为整数并显示它。铸造抛出了一个异常,我不知道为什么它被抛出 #include "stdafx.h" generic<typename tht_1, typename tht_2> ref class mtac{ public: mtac(tht_2 par_1){ System::Console::WriteLine(dycast(par_1)->ToString(

我想创建一个在运行时创建的泛型类来转换泛型类型。下面的版本应该在实例化后将double转换为整数并显示它。铸造抛出了一个异常,我不知道为什么它被抛出

#include "stdafx.h"
generic<typename tht_1, typename tht_2> ref class mtac{
public:
    mtac(tht_2 par_1){
        System::Console::WriteLine(dycast(par_1)->ToString());
    };
    static tht_1 dycast(tht_2 par_1){
        tht_1 treturn;
        System::Console::WriteLine("Atempted casting of {0} to {1}", par_1->GetType()->ToString(), treturn->GetType()->ToString());
        //                                                           System::Double                System::Int32
        try{
            //next statement throws unexpected exception
            treturn = safe_cast<tht_1>(par_1);
        }
        catch(System::Exception^ e){
            System::Console::WriteLine(e->Message);
        };
        return treturn;
    };
};
int main(array<System::String ^> ^args){
    //create generic class type
    System::Type^ otype_1 = int::typeid;
    System::Type^ otype_2 = double::typeid;
    array<System::Type^>^ the_types = {otype_1,otype_2};
    System::Type^ genclass = (*(mtac::typeid)).MakeGenericType(the_types);

    //create parameter arguement list to pass onto constructor of my generic class
    array<System::Object^>^ argstoevl_1 = gcnew array<System::Object^>(1);
    argstoevl_1[0] = gcnew double;
    argstoevl_1[0] = 2.552;

    //Create an instance
    System::Object^ temp_2 = System::Activator::CreateInstance(genclass,argstoevl_1);
    System::Console::ReadLine();
    return 0;
};
#包括“stdafx.h”
通用参考类mtac{
公众:
mtac(第2部分第1部分){
System::Console::WriteLine(dycast(第1部分)->ToString());
};
静态tht_1动态广播(tht_2 par_1){
1个三圈;
System::Console::WriteLine(“将{0}强制转换为{1}”,par_1->GetType()->ToString(),treturn->GetType()->ToString());
//系统::双系统::Int32
试一试{
//next语句引发意外异常
treturn=安全铸造(第1部分);
}
捕获(系统::异常^e){
系统::控制台::写线(e->消息);
};
返回三圈;
};
};
int main(数组^args){
//创建泛型类类型
系统::类型^otype_1=int::类型ID;
系统::类型^otype_2=double::类型ID;
数组^the_types={otype_1,otype_2};
System::Type^genclass=(*(mtac::typeid)).MakeGenericType(类型);
//创建参数参数参数列表以传递给泛型类的构造函数
数组^argstoevl_1=gcnew数组(1);
argstoevl_1[0]=gcnew double;
argstoevl_1[0]=2.552;
//创建一个实例
System::Object^temp_2=System::Activator::CreateInstance(genclass,argstoevl_1);
System::Console::ReadLine();
返回0;
};

我认为
safe\u cast(第1部分)转换为
safe\u cast(第1部分)一旦创建了泛型方法。有人能解释一下我在理解泛型类方面的错误,或者纠正我在理解泛型类方面的缺陷吗。

这不能用强制转换来完成,它需要转换。您在MSDN论坛上得到的答案可能不是您在评测程序后想要的方式,如果您不重复使用表达式,构建和编译表达式的成本将非常高昂

承认您在泛型中使用的类型是可转换类型,并且具有定义良好的转换,从而取得成功。可由System::IConvertible接口表示。每个普通值类型值都实现了它。这使得这项工作:

using namespace System;

generic<typename tht_1, typename tht_2> 
where tht_1 : IConvertible
where tht_2 : IConvertible  
ref class mtac {
public:
    mtac(tht_2 par_1) {
        System::Console::WriteLine(convert(par_1)->ToString());
    };
    static tht_1 convert(tht_2 par_1) {
        return safe_cast<tht_1>(par_1->ToType(tht_1::typeid, nullptr));
    };
};
使用名称空间系统;
通用的
其中tht_1:i可转换
其中tht_2:i可转换
参考类mtac{
公众:
mtac(第2部分第1部分){
System::Console::WriteLine(convert(par_1)->ToString());
};
静态tht_1转换(tht_2 par_1){
返回safe_cast(par_1->ToType(tht_1::typeid,nullptr));
};
};
safe_cast现在只是解除值的绑定,这不是问题。它并不完全等同于Expression::Convert(),该方法使用反射来搜索用户定义的转换运算符。当然非常昂贵,如果你需要这种灵活性,那么你必须付出代价