我有一个类,其中一个字段被分配给类型为T的数组或一个类型为T的dll对象,这个[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,它具有公共浮点数[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包装器对象时,能够提供他们自己的C#数组.
>然后在这两种情况下,我需要它[]可从同一字段(浮点数组或带有[]重载的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, ...
}
}