我有一个第三方库返回一个对象数组的对象数组,我可以将其填充到对象 [] 中:
object[] arr = myLib.GetData(...);
结果数组由 object[] 条目组成,因此您可以将返回值视为某种记录集,其中外部数组表示行,内部数组包含可能未填充某些字段的字段值(锯齿状数组) . 要访问各个字段,我必须像这样进行投射:
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:像詹姆斯一样,我觉得扩展方法有点危险,因为它适用于所有object[]
变量。
@Nair:我为我的实现选择了你的答案,因为它不需要使用 Linq 包装器,我可以int i = (int) arr[row][col];
使用 @quetzalcoatl 和 @Abe Heidebrecht 访问单个字段或整个行object[] row = arr[row];
:感谢关于Cast<>()
.
结论:我希望我可以同时选择 James 和 Nair 的答案,但正如我上面所说,Nair 的解决方案给了我(我认为)最好的灵活性和性能。我添加了一个函数,该函数将使用上面的 Linq 语句“展平”内部数组,因为我还有其他需要使用这种结构的函数。
这是我(大致)实现它的方式(取自 Nair 的解决方案:
公共类 CustomArray { 私有对象 [] 数据;公共 CustomArray(object[] 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
}
}
所以 - 再次 - 谢谢大家!使用这个网站总是一种真正的乐趣和启发。