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

标签 c# generics c++-cli visual-studio-2015 roslyn

我们有一个在 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 中我们得到:

application\Program.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 使得在没有任何编译器窥视的情况下摸索它并失去大量性能太容易了。应用简单的规则,值类型的变量必须永远有帽子。除非堆栈语义(C# 中的 using 语句)是有意的,否则引用类型的变量应始终具有帽子。

关于c# - 作为 c++/cli 函数参数的通用结构在 VS 2015 中导致错误 CS0570,但在 VS2013 中没有,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32008792/

相关文章:

java - 为什么要使用通配符捕获辅助方法?

c# - 覆盖方法时无法更改返回类型,使用泛型时出错

c# - 如何从 C# 中的 C++/CLI dll 访问类型?

c++ - C++/CLI 能否将抽象类从 C++ 返回到 C#?

c# - 在 C# 中的运行时向类型化对象添加 expando 属性

c# - 在 C# 中使用 Excel 双值

c# - 为什么 System.Net.IPAddress 使用签名类型?

delphi - 为什么释放不为空的TList <Int64>不会导致内存泄漏?

arrays - C++ 托管数组大小

c# - Entity Framework : Multiple Where Statements Execution Plan