转换在运行时创建的泛型类型

时间:2014-07-10 13:01:07

标签: 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());
    };
    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;
};

一旦创建了泛型方法,我假设safe_cast<tht_1>(par_1);转换为safe_cast<int>(par_1);。有人可以解释我出错的地方或纠正我理解通用类的缺陷。

1 个答案:

答案 0 :(得分: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));
    };
};

safe_cast&lt;&gt;现在只是将价值取消包装,这不是问题。它与Expression :: Convert()不完全等效,该方法使用Reflection来搜索用户定义的转换运算符。当然非常昂贵,如果您需要这种灵活性,那么您将不得不付出代价。