【发布时间】:2013-06-23 17:51:58
【问题描述】:
我有一个第三方库返回一个对象数组的对象数组,我可以将其填充到一个对象[]中:
object[] arr = myLib.GetData(...);
结果数组由 object[] 条目组成,因此您可以将返回值视为某种记录集,其中外部数组表示行,而内部数组包含可能未填充某些字段的字段值(a锯齿状阵列)。要访问各个字段,我必须像这样投射:
int i = (int) ((object[])arr[row])[col];//access a field containing an int
现在我很懒,我想访问这样的元素:
int i = (int) arr[row][col];
为此,我使用以下 Linq 查询:
object[] result = myLib.GetData(...);
object[][] arr = result.Select(o => (object[])o ).ToArray();
我尝试使用像 object[][] arr = (object[][])result; 这样的简单强制转换,但失败并出现运行时错误。
现在,我的问题:
- 有更简单的方法吗?我感觉有些 漂亮的演员应该可以解决问题吗?
- 我也担心性能 因为我必须重塑大量数据只是为了节省一些演员,所以我 想知道这是否真的值得?
编辑:
谢谢大家的快速解答。
@James:我喜欢你的回答将罪魁祸首包裹在一个新类中,但缺点是我在接收源数组时总是需要进行 Linq 包装,并且索引器需要 row 和 col 值int i = (int) arr[row, col];(我需要像object[] row = arr[row];一样获得完整的行,抱歉,一开始没有发布)。
@Sergiu Mindras:和 James 一样,我觉得扩展方法有点危险,因为它适用于所有 object[] 变量。
@Nair:我为我的实现选择了你的答案,因为它不需要使用 Linq 包装器,我可以使用 int i = (int) arr[row][col]; 访问两个单独的字段或使用 object[] row = arr[row]; 访问整行
@quetzalcoatl 和@Abe Heidebrecht:感谢Cast<>() 的提示。
结论:我希望我可以同时选择 James 和 Nair 的答案,但正如我上面所说,Nair 的解决方案给了我(我认为)最好的灵活性和性能。 我添加了一个函数,该函数将使用上述 Linq 语句“展平”内部数组,因为我还有其他需要使用这种结构的函数。
这是我(大致)实现它的方式(取自 Nair 的解决方案:
公共类 CustomArray { 私有对象[] 数据; 公共CustomArray(对象[] arr) { 数据=arr; }
//get a row of the data
public object[] this[int index]
{ get { return (object[]) data[index]; } }
//get a field from the data
public object this[int row, int col]
{ get { return ((object[])data[row])[col]; } }
//get the array as 'real' 2D - Array
public object[][] Data2D()
{//this could be cached in case it is accessed more than once
return data.Select(o => (object[])o ).ToArray()
}
static void Main()
{
var ca = new CustomArray(new object[] {
new object[] {1,2,3,4,5 },
new object[] {1,2,3,4 },
new object[] {1,2 } });
var row = ca[1]; //gets a full row
int i = (int) ca[2,1]; //gets a field
int j = (int) ca[2][1]; //gets me the same field
object[][] arr = ca.Data2D(); //gets the complete array as 2D-array
}
}
所以 - 再次 - 谢谢大家!使用这个网站总是一种真正的乐趣和启发。
【问题讨论】:
-
什么是运行时错误?
-
这里最昂贵的操作是从
object到int(和其他类型)的拆箱,这似乎是不可避免的,因为你的lib 只返回object[]。你确定它不提供类型化接口吗? -
什么是 var[] arr = myLib.GetData(...);在这种情况下给你?
-
@Andre:返回的数据由不同的类型组成,而且,不,没有类型化接口,因为该函数基本上返回一个select语句的结果,该语句可以包含许多不同类型的字段。