作为c++/cli函数参数的泛型结构在VS 2015中导致错误CS0570,但在VS2013中没有



我们有一个解决方案,它在VS2013中完美编译,但在VS2015中因编译错误而失败。

问题已经缩小到:

我们有一个c#项目a,它定义了一个像这样的通用结构:

public struct MyStruct<T>
{
    public MyStruct(T b)
    {
    }
}

我们有一个c++/cli项目B,它定义了这样一个函数:

public ref class Class1
{
public:
    void BadMethod(MyStruct<int> ^){};
};

最后,我有一个c#命令行项目c,引用项目a和B,并尝试调用BadMethod:

  class Program
    {
        static void Main(string[] args)
        {
            var c = new Class1();
            var s = new MyStruct<int>(0);
            c.BadMethod(s);
        }
    }

在Visual Studio 2013(及更早版本(中,它编译时没有任何问题,但在Visual Studio 2015中,我们得到了:

applicationProgram.cs(18,15,18,24): error CS0570: 'Class1.BadMethod(?)' is not supported by the language

我曾尝试使用Visual Studio 2015工具集编译c++/cli项目,但错误仍然存在。

使用泛型类而不是结构似乎是可行的。

   void BadMethod(MyStruct<int> ^){};

值得注意的是,一个新的VS版本经常因为编程错误而受到指责。MyStruct类型是值类型。但是您将参数类型声明为引用类型变量。记下你用过的^帽子。

不幸的是,C++/CLI编译器确实支持这一点。CLR也是如此,在将值传递给方法调用之前,必须先将其装箱。非常低效,使用值类型的目的总是避免装箱。但是,CLR中没有可用于这种装箱类型的类型注释,它在元数据中变为System::ValueType。使用运行时检查值是否为预期类型。效率越低,这就意味着大笔钱。

C#语言根本不支持这一点,并对必须对值进行装箱表示不满。如果没有任何方法来检查它是否是所需的值类型,它就会非常重视静态类型检查。

修复方法非常简单,只需省略^,这样参数就可以按值传递,而不必装箱。如果您想通过引用传递值,但问题不清楚,则必须使用%

C++/CLI可能是检查其余代码的好主意,它让你很容易在编译器没有任何提示的情况下弄丢这一点并丢失大量性能。应用简单规则,值类型的变量必须从不具有帽子。引用类型的变量应该始终具有hat,除非打算使用堆栈语义(使用C#中的语句(。

最新更新