I\'m using a linq query to output an int array. But I need to pass this into a method that only accepts int?[].
So after searching on ways to convert int[] to int?[] I
This extension method, ToArrayOrNull
, does not change the type of the contents. seq
is an IEnumerable
of T
. result
is an array of T
(which you sometimes return as null
, but that's still an array of T
.
If you really want to convert an IEnumerable<T>
to an IEnumerable<T?>
(or an array of T?
), you should put some constraints on the type parameter (it should be struct
, meaning a value type, one that cannot be null), and convert each item instead of the whole result, something like:
public static T?[] ToArrayOfNullable<T>(this IEnumerable<T> seq)
where T : struct
{
return seq.Select(val => (T?)val).ToArray();
}
Although I would return an IEnumerable<T?>
here and convert to an array later, to keep this method simple.
Don't do the wrong thing first, and then fix it up afterwards. Do the right thing straigtaway. You know you need an int?[]
. So create an int?[]
. Don't first create an int[]
and then fix it up. You can get it to work, but it's pointlessly complicated.
int?[] vids1 = new[] { "", "1", "2", "3" }
.Where(x => !String.IsNullOrWhiteSpace(x))
.Select(x => (int?) Convert.ToInt32(x))
.ToArray();
The reason I'm strongly suggesting not even trying to make your ToArrayOrNull
work is also because it doesn't even come close to doing what you're saying it should do. You can make it work, but you have to understand what's supposed to be going on before starting on your coding. Leave this for now as long as you don't need it anyway, and when you look back later you'll probably suddenly see it.
int?[]
is an array of int?
. All you need is change lambda in Select
, to return an int?
:
int?[] vids2 = new[] { "", "1", "2", "3" }
.Where(x => !String.IsNullOrWhiteSpace(x))
.Select(x => (int?)Convert.ToInt32(x))
.ToArray();
If you already have an int[]
, you can use Cast()
to cast the elements to int?
int[] ints = { 1, 2, 3 };
int?[] nullableInts = ints.Cast<int?>().ToArray();
I know that it's not correct answer for your question but there is a bit different solution - if you want to keep order and collection length.
public static class EnumerableExtensions
{
public delegate bool ParseDelegate<T>(string input, out T value) where T : struct;
public static T?[] ToNullable<T>(this string[] values, ParseDelegate<T> parseMethod) where T : struct
{
IEnumerable<T?> cos = values.Select(s =>
{
T result;
if (parseMethod(s, out result))
{
return (T?)result;
}
return null;
});
return cos.ToArray();
}
}
usage:
var cos = new[] { "1", "", "3", "True" };
int?[] eee= cos.ToNullable<int>(int.TryParse); // 1, null, 3, null
float?[] ada = cos.ToNullable<float>(float.TryParse); // 1, null, 3, null
bool?[] asd3 = cos.ToNullable<bool>(bool.TryParse); // null, null, null, true
How about this using Cast<>
and a type constraint making T
a struct
:
public static IEnumerable<T?> ToArrayOrNull<T>(this IEnumerable<T> seq)
where T : struct
{
if (seq.Count() == 0)
return null;
return seq.Cast<T?>().ToArray();
}