我使用linq查询输出一个int数组。但是我需要将它传递给一个只接受int?[]的方法。
所以在搜索了将int []转换为int的方法之后?[]我找到了似乎可行的东西here
以下代码是一个简化示例,显示了哪些有效且无效。
using System;
using System.Collections.Generic;
using System.Web;
using System.Linq;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
// working...
int[] vids1 = new[] { "", "1", "2", "3" }
.Where(x => !String.IsNullOrWhiteSpace(x))
.Select(x => Convert.ToInt32(x))
.ToArray();
foreach(int i in vids1)
{
System.Diagnostics.Debug.WriteLine(i.ToString());
}
// not working...
int?[] vids2 = new[] { "", "1", "2", "3" }
.Where(x => !String.IsNullOrWhiteSpace(x))
.Select(x => Convert.ToInt32(x))
.ToArrayOrNull();
}
}
public static class IEnumerableExtensions
{
public static T?[] ToArrayOrNull<T>(this IEnumerable<T> seq)
{
var result = seq.ToArray();
if (result.Length == 0)
return null;
return result;
}
}
}
我已经玩过这种扩展方法试图让它传回int?[]类型,但还没有运气。
如何让我的IEnumerable扩展ToArrayOrNull
传回可以为空的类型?
答案 0 :(得分:3)
int?[]
是int?
的数组。您只需在Select
中更改lambda,即可返回int?
:
int?[] vids2 = new[] { "", "1", "2", "3" }
.Where(x => !String.IsNullOrWhiteSpace(x))
.Select(x => (int?)Convert.ToInt32(x))
.ToArray();
如果您已有int[]
,则可以使用Cast()
将元素转换为int?
int[] ints = { 1, 2, 3 };
int?[] nullableInts = ints.Cast<int?>().ToArray();
答案 1 :(得分:2)
此扩展方法ToArrayOrNull
不会更改内容的类型。 seq
是IEnumerable
T
。 result
是T
的数组(您有时会将其返回为null
,但这仍然是T
的数组。
如果你真的想要将IEnumerable<T>
转换为IEnumerable<T?>
(或T?
数组),你应该对类型参数设置一些约束(它应该是{{1 },意思是一个值类型,一个不能为null),并转换每个项而不是整个结果,如:
struct
虽然我会在这里返回 public static T?[] ToArrayOfNullable<T>(this IEnumerable<T> seq)
where T : struct
{
return seq.Select(val => (T?)val).ToArray();
}
并稍后转换为数组,但要保持此方法的简单。
答案 2 :(得分:1)
不要先做错事,然后再修好。做正确的事情straigtaway。你知道你需要一个int?[]
。所以创建一个int?[]
。不要先创建int[]
,然后再修复它。你可以让它发挥作用,但它毫无意义的复杂。
int?[] vids1 = new[] { "", "1", "2", "3" }
.Where(x => !String.IsNullOrWhiteSpace(x))
.Select(x => (int?) Convert.ToInt32(x))
.ToArray();
我强烈建议您甚至不尝试让ToArrayOrNull
工作的原因也是因为它甚至没有接近做你应该做的事情。你可以使它工作,但你必须了解在开始编码之前应该发生什么。只要你不需要它,现在就离开这个,当你回顾过去时,你可能会突然看到它。
答案 3 :(得分:1)
使用Cast<>
以及使T
成为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();
}
答案 4 :(得分:1)
我知道这不是你的问题的正确答案,但有一个不同的解决方案 - 如果你想保持订单和收集长度。
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();
}
}
用法:
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