Alex Aparin
Alex Aparin

Reputation: 4512

Conflict of tracking reference in c#

I wrote managed class in C++/CLI:

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

Then, I am using methods in c# console application, like this:

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

I really don't understand this difference. C# treats signature of func1 and func2 as:

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

Upvotes: 0

Views: 370

Answers (1)

Hans Passant
Hans Passant

Reputation: 941635

   void func1(Foo% foo)

This is an implicit reference. It is a native C++ feature, equivalent to Foo& if Foo were an unmanaged type. C++/CLI supports it as well, it tries to be as C++-like as it can. To a fault sometimes, it would arguably be a lot clearer if they had permitted Foo^& instead.

But it is not a feature of other .NET languages, like C#, as you found out, they don't have any syntax to express the same thing. Not in the least because these languages try to hide the differences between object references and values as much as possible. To a fault sometimes. It is not an MSIL feature either, requiring the C++/CLI compiler to implement it. Much like a C++ compiler does. The argument type is actually Foo^ in the metadata but with a [modopt] to annotate the method argument. Enough for the C# compiler to know that it is forbidden fruit, too likely to cause method overload resolution problems.

Since Foo is a reference type, you really do have to use Foo^. Or Foo^% if you meant to pass the object reference by reference, only useful if your method creates a new Foo object.

Upvotes: 2

Related Questions