[英]C# cast exception in C# dll
我有一个类,其中一个字段被分配给类型为T的数组或一个类型为T的dll对象, this [int i]
有一个模拟数组的重载(它使用非托管内存并使用重载访问)
public T this[int i]
{
get
{
return ((T[])array)[i]; // can't use return array[i] directly
}
set { }
}
当我使用dll对象时,它会抛出强制转换异常。 我认为(T[])
将触发对象的重载[]
而不是强制转换为float[]
但它总是强制转换为float[]
而对象类型是FloatArr
,它具有public float this[int i]
。
有没有办法将原始数组视为转换同时将其他自定义类型视为重载触发器?
如果这是不可能的,如何返回类型T
而返回类型如float
可以从一个简单的float数组或一些带有重载的自定义类型收集返回float? 我不想一个接一个地添加float,int,byte,double,char,.... 无论对象字段是C#数组还是带有重载索引器的自定义类型,我都需要T
工作吗?
我真正需要的是:
// developer supplies here with his/hers own array
// or this library uses its own fast C++ wrapper with a [] overload
public object array { get; set; }
// returns float, int, byte
public T this[int i]
{
get
{
return array[i]; // float[], int[], FloatArr[], ...
}
set { }
}
编辑:如果这是一个糟糕的设计模式请告诉我。 无论是C#数组还是带有[]
重载的C ++包装器C#dll对象,我都需要这个类来处理属性。
编辑-2:这是我心中的用法:
MyArr<float> gpu = new MyArr<float>(1024);
gpu.array=new float[1024];
gpu[35]=40;
or
MyArr<float> gpu = new MyArr<float>(1024);
gpu.allocateUnManagedToArray(); // now array field is a custom object
gpu[35]=40;
编辑3:这是我放入数组字段的自定义类:
public class FloatArr
{
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;
}
}
}
}
编辑-4:只是因为我不清楚:
[]
重载的类作为数组工作 []
! []
可从同一字段索引(浮点数组或带有[]
重载的C ++包装器)。 当然,我可以逐个编写float int byte的所有条件,但这需要更长的时间。 通用类很容易,它应该很容易,但我在这里遗漏了一些我看不到的东西。 当我添加struct数组时,代码将来会增长得更多,所以我无助地需要泛型类。
您需要做的不是使用数组,而是使用IList<T>
接口。 然后,您需要使您的自定义类实现该接口。
class FloatArr : IList<float>
{
//(snip)
// p and hArr's decliration and assignment
//(snip)
public float this[int index]
{
get
{
unsafe
{
float* p = (float*)hArr.ToPointer();
return *(p + i);
}
}
set
{
unsafe
{
float* p = (float*)hArr.ToPointer();
*(p + i) = value;
}
}
}
IEnumerator<float> IEnumerable<float>.GetEnumerator()
{
throw new NotImplementedException();
}
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
void ICollection<float>.Add(float item)
{
throw new NotImplementedException();
}
void ICollection<float>.Clear()
{
throw new NotImplementedException();
}
bool ICollection<float>.Contains(float item)
{
throw new NotImplementedException();
}
void ICollection<float>.CopyTo(float[] array, int arrayIndex)
{
throw new NotImplementedException();
}
bool ICollection<float>.Remove(float item)
{
throw new NotImplementedException();
}
int ICollection<float>.Count
{
get { throw new NotImplementedException(); }
}
bool ICollection<float>.IsReadOnly
{
get { throw new NotImplementedException(); }
}
int IList<float>.IndexOf(float item)
{
throw new NotImplementedException();
}
void IList<float>.Insert(int index, float item)
{
throw new NotImplementedException();
}
void IList<float>.RemoveAt(int index)
{
throw new NotImplementedException();
}
}
如果您不需要写入数组并且只读取,则可以使用IReadOnlyList<T>
大大简化该类
class FloatArr : IReadOnlyList<float>
{
//(snip)
// p and hArr's decliration and assignment
//(snip)
public float this[int index]
{
get
{
unsafe
{
float* p = (float*)hArr.ToPointer();
return *(p + i);
}
}
}
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
IEnumerator<float> IEnumerable<float>.GetEnumerator()
{
throw new NotImplementedException();
}
int IReadOnlyCollection<float>.Count
{
get { throw new NotImplementedException(); }
}
}
然后您的容器类更改为
// developer supplies here with his/hers own array
// or this library uses its own fast C++ wrapper with a [] overload
public IList<T> array { get; set; }
// returns float, int, byte
public T this[int i]
{
get
{
return array[i]; // float[], int[], FloatArr, ...
}
set
{
array[i] = value;
}
}
要么
// developer supplies here with his/hers own array
// or this library uses its own fast C++ wrapper with a [] overload
public IReadOnlyList<T> array { get; set; }
// returns float, int, byte
public T this[int i]
{
get
{
return array[i]; // float[], int[], FloatArr, ...
}
}
另一种选择而不是实现IList<T>
或IReadOnlyList<T>
您可以使用dynamic
关键字来执行运行时绑定而不是编译时绑定。 然而,与使用IList<T>
或IReadOnlyList<T>
相比,这将有更糟糕的性能
// developer supplies here with his/hers own array
// or this library uses its own fast C++ wrapper with a [] overload
public dynamic array { get; set; }
// returns float, int, byte
public T this[int i]
{
get
{
return array[i]; // float[], int[], FloatArr[], ...
}
set
{
array[i] = value;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.