我有一个第三方库返回一个对象数组的对象数组,我可以填充到一个对象[]:
object[] arr = myLib.GetData(...);
Run Code Online (Sandbox Code Playgroud)
结果数组由object []条目组成,因此您可以将返回值视为某种记录集,其中外部数组表示行,而内部数组包含可能未填充某些字段的字段值(锯齿状数组) .要访问各个字段,我必须像:
int i = (int) ((object[])arr[row])[col];//access a field containing an int
Run Code Online (Sandbox Code Playgroud)
现在因为我很懒,我想要访问这样的元素:
int i = (int) arr[row][col];
Run Code Online (Sandbox Code Playgroud)
为此,我使用以下Linq查询:
object[] result = myLib.GetData(...);
object[][] arr = result.Select(o => (object[])o ).ToArray();
Run Code Online (Sandbox Code Playgroud)
我尝试使用简单的强制转换,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<>().
Conclusion: I wish I could choose both James' and Nair's answer, but as I stated above, Nair's solution gives me (I think) the best flexibility and performance. I added a function that will 'flatten' the internal array using the above Linq statement because I have other functions that need to be fed with such a structure.
Here is how I (roughly) implemented it (taken from Nair's solution:
public class CustomArray { private object[] data; public CustomArray(object[] arr) { data = 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
}
}
Run Code Online (Sandbox Code Playgroud)
So - again - thank you all! It always is a real pleasure and enlightenment to use this site.
您可以创建一个包装类来隐藏丑陋的转换,例如
public class DataWrapper
{
private readonly object[][] data;
public DataWrapper(object[] data)
{
this.data = data.Select(o => (object[])o ).ToArray();
}
public object this[int row, int col]
{
get { return this.data[row][col]; }
}
}
Run Code Online (Sandbox Code Playgroud)
用法
var data = new DataWrapper(myLib.GetData(...));
int i = (int)data[row, col];
Run Code Online (Sandbox Code Playgroud)
还有机会使包装器通用DataWrapper<int>,但是,我不确定您的数据集合是否都是相同的类型,返回object保持它的通用性足以让您决定需要什么样的数据类型.
几乎没有发布类似的答案来执行类似的操作。仅当您想访问时,这才会有所不同
int i = (int) arr[row][col];
Run Code Online (Sandbox Code Playgroud)
为了展示这个想法
public class CustomArray
{
private object[] _arr;
public CustomArray(object[] arr)
{
_arr = arr;
}
public object[] this[int index]
{
get
{
// This indexer is very simple, and just returns or sets
// the corresponding element from the internal array.
return (object[]) _arr[index];
}
}
static void Main()
{
var c = new CustomArray(new object[] { new object[] {1,2,3,4,5 }, new object[] {1,2,3,4 }, new object[] {1,2 } });
var a =(int) c[1][2]; //here a will be 4 as you asked.
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3212 次 |
| 最近记录: |