Reputation: 8753
Having an DataView tmp
, I need to create from two columns of tmp
an array of array (probably this is not the correct term in c#, I'm new to it) to be passed to DotNet.Highcharts. The final structure should be something like:
[[5, 2], [6, 3], [8, 2]]
First, I used this code:
Object[] result = new object[tmp.Count];
result = tmp.Table
.AsEnumerable()
.Select(row => new Object[] { row.Field<DateTime>("DATE"),
Convert.ToDouble(row.Field<string>("VALUE"))})
.ToArray();
The problem came when I try to substitute an element of result
with a Point
(to define custom marker e.g.):
if (something[k] == "TRUE") // if for a given row a generic condition is true
{
result[k] = new DotNet.Highcharts.Options.Point
{
X = Tools.GetTotalMilliseconds((DateTime)tmp[k].Row["DATE"]),
Y = Convert.ToInt32(tmp[k].Row["VALUE"]),
Marker = new PlotOptionsSeriesMarker
{
Symbol = "url(/Proj/images/cross.png)"
}
};
}
In runtime I get: A first chance exception of type 'System.ArrayTypeMismatchException' occurred in App_Web_pz3kxbru.dll
I found a fix doing this to create result
:
Object[] result = new object[tmp.Count];
for (int j = 0; j < tmp.Count; j++)
{
result [j] = new object[] { (DateTime)tmp[j].Row["DATE"],
Convert.ToDouble(tmp[j].Row["VALUE"])};
}
Now everything works fine. However I don't have any clue of what actually I did... Can you please explain me the difference between the methods I used to obtain result
.
Upvotes: 1
Views: 2240
Reputation: 89285
The only difference I can notice is, Convert.ToDouble
in the first approach :
.Select(row => new Object[] { row.Field<DateTime>("DATE"),
Convert.ToDouble(row.Field<string>("VALUE"))})
versus Convert.ToInt32
in the second :
new object[] { (DateTime)tmp[j].Row["DATE"],
Convert.ToInt32(tmp[j].Row["VALUE"])};
UPDATE :
The first approach create a new array, replacing the original array which is array of object (Object[]
) with new array which is 'array of array' (Object[][]
), hence causes a problem (co-variant array problem).
The second approach doesn't create a new array, but fill in each slot in the original array of object with an array. So in this case, result
is still array of object, doesn't get changed to 'array of array', hence can avoid exception.
If you favor the LINQ approach, this will do (still need a counter variable) :
Object[] result = new object[tmp.Count];
int i = 0;
result = tmp.Table
.AsEnumerable()
.ForEach(row => result[i++] = new Object[] { row.Field<DateTime>("DATE"),
Convert.ToDouble(row.Field<string>("VALUE"))});
or better yet, simply cast the array of object to object :
result = tmp.Table
.AsEnumerable()
.Select(row => (Object)new Object[] { row.Field<DateTime>("DATE"),
Convert.ToDouble(row.Field<string>("VALUE"))})
.ToArray();
Upvotes: 1