在托管的c ++类中,我应该使用我在另一个库中实现的C#类的引用还是实例?
考虑这个例子:
// MyManagedClass.h
#pragma once
using namespace System::Collections::Generic;
using namespace My::Namespace::MyCSharpLib;
namespace My::Namespace::MyManagedLib
{
public ref class MyManagedClass
{
public:
MyCSharpClass myInst; // i have an instance!
MyCSharpClass ^myRef; // need to do gcnew
List<MyCSharpClass ^> listInst; // i have an instance!
List<MyCSharpClass ^> ^listRef; // need to do gcnew
};
}
Run Code Online (Sandbox Code Playgroud)
然后从C#代码调用托管类:
// driver.cs
using My.Namespace.MyCSharpLib;
using My.Namespace.MyManagedLib;
public class Driver
{
private static void Main(string[] args)
{
MyManagedClass mmc = new MyManagedClass();
DoStuff(mmc);
}
}
Run Code Online (Sandbox Code Playgroud)
我的直觉告诉我,我应该使用myRef,listRef因为如果这是在C#中实现的话,那就是我要做的事情.但为什么我可以直接实例化一个实例MyCSharpClass呢?这样做的后果是什么?如果我的班级只有一个MyCSharpClass对象集合,那么直接初始化集合是否有害?
C++/CLI有一个称为堆栈语义的功能,当您将引用类型成员声明为值类型(MyCSharpClass myInst;)时,您正在使用该功能.
gcnew仍然被调用,但你没有看到这段代码,因为编译器会自动将它注入你的默认构造函数.请注意,它还会生成要处理的代码myInst!
下面是编译器将为您的类发出的MSIL的(伪)C++/CLI代码:
构造函数:
MyManagedClass()
{
myInst = gcnew MyCSharpClass();
}
Run Code Online (Sandbox Code Playgroud)
配置:
void Dispose(bool dispose)
{
if (dispose)
{
try
{
this->~MyManagedClass();
}
finally
{
delete myInst;
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:
关于你关于反响的问题:手动分配gcnew意味着当你的MyManagedClass对象死亡时,指向的对象myRef仍然会挂起,直到垃圾收集器清理它为止; 而通过使用堆栈语义,您可以使用更加确定的方法来控制对象的生命周期,而无需自己编写Dispose方法.
这也意味着当使用堆栈语义时,你必须小心你与谁共享对象...
| 归档时间: |
|
| 查看次数: |
131 次 |
| 最近记录: |