例如,作为重载的[]
setter-getter,
public T this[int i]
{
get
{
unsafe
{
T* p = (T*)hArr.ToPointer(); // hArr is a C++ object pointer(IntPtr)
return *(p + i);
}
}
set
{
unsafe
{
T* p = (T*)hArr.ToPointer();
*(p + i) = value;
}
}
}
并且编译器向托管类型T
抱怨(强调)关于它“无法获取...的地址”。
我知道T
在运行时只会是float,double,int或byte,但我不知道如何告诉编译器,所以它信任我。
为什么我不能使用它,无论如何都是指针,如果我不小心,我可以溢出任何类型的数组。
如何在不慢于:
的情况下实现这一目标(以类似的方式) public float this[int i]
{
get
{
unsafe
{
float* p = (float*)hArr.ToPointer();
return *(p + i);
}
}
set {
unsafe
{
float* p = (float*)hArr.ToPointer();
*(p + i) = value;
}
}
}
我不仅关心这里的性能,还关注代码简洁性。 (所有T类型的一个代码)我想,接口在这里无法帮助。
答案 0 :(得分:3)
C#restricts指针类型
sbyte
,byte
,short
,ushort
,int
,uint
,long
,ulong
,char
,float
,double
,decimal
或bool
,enum
类型,struct
类型,仅包含非托管类型的字段。最后一点是关键,因为编译器必须能够验证您尝试制作指针的struct
是否“合法”。否则,您将能够传递T
struct
,该string
字段引用被禁止的托管类型(例如,public int GetInt(int i) {
unsafe {
var p = (int*)hArr.ToPointer();
return *(p + i);
}
public void SetInt(int i, int val) {
unsafe {
var p = (int*)hArr.ToPointer();
*(p + i) = val;
}
}
public float GetFloat(int i) {
unsafe {
var p = (int*)hArr.ToPointer();
return *(p + i);
}
public void SetFloat(int i, float val) {
unsafe {
var p = (float*)hArr.ToPointer();
*(p + i) = val;
}
}
... // and so on
)。
由于您有兴趣为四种数据类型提供此行为,因此您应该能够通过提供四个重载来解决此问题:
String fspath = FileSystemStorage.getInstance().getAppHomePath();
String url = "http://example.com/getSomeJSON.php";
ConnectionRequest cr = new ConnectionRequest(url, false);
cr.setDestinationFile(fspath + "mylocalfile.json");
NetworkManager.getInstance().addToQueue(cr);
运行时效率将保持不变,假设编译器有足够的信息在编译时解决重载。