gpt4 book ai didi

C# dll 中的 C# 转换异常

转载 作者:行者123 更新时间:2023-11-30 12:22:00 25 4
gpt4 key购买 nike

我有一个带有字段的类,该字段分配给类型 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,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 对象。

Edit-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;

Edit-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;
}
}
}
}

Edit-4:以防万一我不清楚:

  • 我有一个带有 [] 重载的类,可以用作数组
  • 但它也有一个字段,有时会给出另一个重载 [] 的类!
  • 现在我只需要其他开发人员能够在他们不想要此类的自己的 C++ 包装器对象时提供他们自己的 C# 数组。
  • 然后在这两种情况下,我都需要它可以从同一字段( float 组或带有 [] 重载的 C++ 包装器)进行索引[]

当然,我可以将 float int byte 的所有条件都一一写出来,但这会花费更长的时间。通用类很简单,应该很容易,但我在这里遗漏了一些我看不到的东西。当我添加结构数组时,将来代码会增长得更多,所以我无奈地需要泛型类。

最佳答案

您需要做的不是使用数组,而是使用 IList<T> 界面。然后,您需要让您的自定义类实现该接口(interface)。

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, ...
}
}

关于C# dll 中的 C# 转换异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42937705/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com