C#dll中的C#强制转换异常

侯赛因·图格鲁·布基西克

我有一个类,该类的字段分配给类型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[]但是它总是强制转换为,并且对象类型为FloatArrhas public float this[int i]

有没有一种方法可以将基本数组视为强制转换,同时将其他自定义类型视为重载触发器?

如果这是不可能的,那么如何在返回类型的T同时返回类型,例如float可以从简单的float数组或某些带有重载的自定义类型中收集返回的类型以返回float?我不想一一添加float,int,byte,double,char等。我是否需要T为所有类型工作,无论对象字段是C#数组还是带有重载索引器的自定义类型?

我实际需要的是:

    // 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#数组。
  • 然后,在这两种情况下,我都需要[]从同一字段(可[]重载的float数组或C ++包装器)进行索引

当然,我可以一一写出所有关于float int字节的条件,但是那将花费更长的时间。泛型类很容易,应该很容易,但是我在这里遗漏了一些看不见的东西。当我添加结构数组时,代码将来会增长得更多,因此我无助地需要泛型类。

斯科特·张伯伦

您需要执行的操作不是使用数组,而是使用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, ...
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章