【问题标题】:Conflict of tracking reference in c#c#中跟踪引用的冲突
【发布时间】:2016-07-22 16:06:12
【问题描述】:

我用 C++/CLI 编写了托管类:

public ref class Foo
{
public:
   void func1(Foo% foo){}
   void func2(Foo^% foo){}
};

然后,我在 c# 控制台应用程序中使用方法,如下所示:

Foo foo = new Foo();
Foo foo2 = new Foo();
foo.func1(ref foo2);  // getting error
foo.func2(ref foo2);  // OK

我真的不明白这个区别。 C# 将 func1 和 func2 的签名视为:

void func1(Foo);
void func2(ref Foo);

【问题讨论】:

  • ^ 表示ref。你不明白什么?
  • 我以为^是指针的意思
  • 哦,我好像明白了,谢谢。
  • @SLaks, nope ^ 表示 托管句柄,它在 C# 中隐含用于引用类型,等效于 C++ 中的 *。如果Foo 是引用类型,^% 的含义与 C# 的 ref 相同。 % 单独是一个跟踪引用,它在 C# 中没有等价物 - 就像 C++ 中的 & 一样,将其视为不能为空的对象引用。如果Foo 是值类型,它也等效于C# 中的ref。 C++/CLI 对这些东西非常更加明确。在 OP 的示例中,% 添加了 ref 语义,^ 只是由于 Foo 是引用类型而需要的。

标签: c# .net c++-cli


【解决方案1】:
   void func1(Foo% foo)

这是一个隐式引用。它是native C++ feature,如果 Foo 是非托管类型,则相当于 Foo&。 C++/CLI 也支持它,它尽可能地像 C++ 一样。有时,如果他们允许Foo^& 代替,可能会更清楚。

但它不是其他 .NET 语言(如 C#)的特性,正如您发现的那样,它们没有任何语法来表达相同的东西。至少不是因为这些语言试图尽可能地隐藏对象引用和值之间的差异。有时会犯错。它也不是 MSIL 功能,需要 C++/CLI 编译器来实现它。很像 C++ 编译器。参数类型实际上是元数据中的Foo^,但使用a [modopt] 来注释方法参数。足以让 C# 编译器知道它是禁果,太容易导致方法重载解析问题。

由于 Foo 是一个引用类型,你确实必须使用 Foo^。或者 Foo^% 如果您打算通过引用传递对象引用,则仅在您的方法创建新的 Foo 对象时有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-07
    相关资源
    最近更新 更多