Convert type 'int?[]' to 'int[]'

  • Thread starter Thread starter Stuart Shay
  • Start date Start date
S

Stuart Shay

Hello all

I have the following LINQ Query

int?[] reviews = (from Review review in bk.Reviews
where (review.Book == bk.ID)
select review.Rating).ToArray();


I need to bind the results to a control that only excepts int[]

If the array in not empty how do I Cast the int?[] array to int[]

Thanks
Stuart
 
Stuart said:
I have the following LINQ Query

int?[] reviews = (from Review review in bk.Reviews
where (review.Book == bk.ID)
select review.Rating).ToArray();


I need to bind the results to a control that only excepts int[]
If the array in not empty how do I Cast the int?[] array to int[]

There must be several ways.

First that came to my mind was:

int[] reviews2 = reviews.Cast<int>().ToArray();

Arne
 
I need to bind the results to a control that only excepts int[]

If the array in not empty how do I Cast the int?[] array to int[]

Your best bet is to use the ?? operator, probably, and foreach on the
int?[] to convert it to an int[]. A quick example:

===== BEGIN C# CODE =====
using System;

public class EntryPoint {
public static void Main() {
int?[] nullable = {0, null, 24, 42, 64, null, 7};
int[] nonnullable = new int[nullable.Length];
int counter = 0;

// This is the important part, and we see below how this works
foreach(int? val in nullable) {
nonnullable[counter++] = val ?? 0;
}

Console.Write("nullable: ");
foreach(int? i in nullable) {
if(i == null) {
Console.Write("(null), ");
} else {
Console.Write("{0}, ", i);
}
}
Console.CursorLeft -= 2;
Console.Write(" ");
Console.WriteLine();

Console.Write("nonnullable: ");
foreach(int i in nonnullable) {
Console.Write("{0}, ", i);
}
Console.CursorLeft -= 2;
Console.Write(" ");
Console.WriteLine();
}
}
===== END C# CODE =====

You can compile this and you'll get a list of numbers, one with (null)
values in them and the other with 0s instead of (null) values.

You can certainly write a simple method whose sole purpose in life is
to convert int?[] to int[]. The following I've tested as shown, and it
works. It ought to work with any other such type:

===== BEGIN C# CODE =====
using System;

public class EntryPoint {
public static void Main() {
int?[] nullable = {0, null, 24, 42, 64, null, 7};
int[] nonnullable = NullableToRegular<int>(nullable);
int counter = 0;

foreach(int? val in nullable) {
nonnullable[counter++] = val ?? 0;
}

Console.Write("nullable: ");
foreach(int? i in nullable) {
if(i == null) {
Console.Write("(null), ");
} else {
Console.Write("{0}, ", i);
}
}
Console.CursorLeft -= 2;
Console.Write(" ");
Console.WriteLine();

Console.Write("nonnullable: ");
foreach(int i in nonnullable) {
Console.Write("{0}, ", i);
}
Console.CursorLeft -= 2;
Console.Write(" ");
Console.WriteLine();
}

public static G[] NullableToRegular<G>(Nullable<G>[] items) where G :
struct {
G[] retval = new G[items.Length];
int counter = 0;

foreach(Nullable<G> item in items) {
retval[counter++] = item ?? default(G);
}

return(retval);
}
}
===== END C# CODE =====

There may be a .NET built-in method somewhere that does something like
this, I am not certain. But if not, this one should be pretty close to
what you're looking for. It only took me a few minutes to come up with
once I learned how to write a generic method. Incidentally, I used
"CLR via C#", 2nd ed., Microsoft Press to come up with the information
to write that generic method... good book, great reference.

HTH,
Mike
 
Stuart said:
I need to bind the results to a control that only excepts int[]
If the array in not empty how do I Cast the int?[] array to int[]

There must be several ways.

First that came to my mind was:

int[] reviews2 = reviews.Cast<int>().ToArray();

What does that do, precisely? I didn't know Nullable<T> had a generic
Cast method. Is that some sort of extension? I don't see it in MSDN.

--- Mike
 
int counter = 0;

foreach(int? val in nullable) {
nonnullable[counter++] = val ?? 0;
}

In the second listing, that part needs to be removed to prove what I
stated to be correct. For whatever reason, I did an Undo or something
in my editor before I copied and pasted and it came back. Oops.

--- Mike
 
Stuart said:
Hello all
I have the following LINQ Query

int?[] reviews = (from Review review in bk.Reviews
where (review.Book == bk.ID)
select review.Rating).ToArray();


I need to bind the results to a control that only excepts int[]
If the array in not empty how do I Cast the int?[] array to int[]

Thanks
Stuart

There is no way to cast an int? array to an int array (not even using
unsafe code), as an int? is not the same size as an int.

You have to create a new array and copy each value to it. There are of
course many different ways of doing that, but there is no way around it.
 
Göran Andersson skrev:
Stuart said:
Hello all
I have the following LINQ Query

int?[] reviews = (from Review review in bk.Reviews
where (review.Book == bk.ID)
select review.Rating).ToArray();


I need to bind the results to a control that only excepts int[]
If the array in not empty how do I Cast the int?[] array to int[]

Thanks
Stuart

There is no way to cast an int? array to an int array (not even using
unsafe code), as an int? is not the same size as an int.

You have to create a new array and copy each value to it. There are of
course many different ways of doing that, but there is no way around it.
Secondly you have to make a decision on what value to use in the int
array, or if you want to leave them out when you find (int?[n]
== null) (!int?[n].HasValue)
 
Michael said:
Stuart said:
I need to bind the results to a control that only excepts int[]
If the array in not empty how do I Cast the int?[] array to int[]
There must be several ways.

First that came to my mind was:

int[] reviews2 = reviews.Cast<int>().ToArray();

What does that do, precisely? I didn't know Nullable<T> had a generic
Cast method. Is that some sort of extension? I don't see it in MSDN.

Yes - it is an extension method.

But since you use LINQ then you must be on .NET 3.5 !

Arne
 
Back
Top