简体   繁体   English

如何将int []类型转换为int?[]

[英]How to convert type int[] to int?[]

I'm using a linq query to output an int array. 我正在使用linq查询来输出一个int数组。 But I need to pass this into a method that only accepts int?[]. 但是我需要将其传递给仅接受int?[]的方法。

So after searching on ways to convert int[] to int?[] I found something that seemed might work here 因此,在研究了将int []转换为int?[]的方法之后,我发现似乎在这里可行

The following code is a simplified example that shows what is working and not working. 下面的代码是一个简化的示例,显示了什么在起作用,什么不起作用。

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;
        }
    }
}

I've played around with this extension method trying to get it to pass back int?[] type, but no luck as of yet. 我一直在尝试使用这种扩展方法来尝试使其传回int?[]类型,但到目前为止还没有运气。

How can I get my IEnumerable extension ToArrayOrNull to pass back nullable types? 如何获得IEnumerable扩展ToArrayOrNull来传回可为空的类型?

int?[] is an array of int? int?[]int?的数组int? . All you need is change lambda in Select , to return an int? 您只需要在Select更改lambda即可返回一个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[] ,则可以使用Cast()将元素转换为int?

int[] ints = { 1, 2, 3 };
int?[] nullableInts = ints.Cast<int?>().ToArray();

This extension method, ToArrayOrNull , does not change the type of the contents. 此扩展方法ToArrayOrNull不会更改内容的类型。 seq is an IEnumerable of T . seqTIEnumerable result is an array of T (which you sometimes return as null , but that's still an array of T . resultT的数组(有时有时返回null ,但仍然是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: 如果你真的想转换一个IEnumerable<T>IEnumerable<T?> (或阵列T?你应该把一些约束的类型参数(这应该是struct ,意思是值类型,一个不能为null),然后转换每个项目而不是整个结果,例如:

    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. 尽管我将在此处返回IEnumerable<T?>并稍后转换为数组,以使此方法保持简单。

Don't do the wrong thing first, and then fix it up afterwards. 不要先做错事,然后再解决。 Do the right thing straigtaway. 做正确的事情。 You know you need an int?[] . 您知道您需要一个int?[] So create an int?[] . 那么创建一个int?[] Don't first create an int[] and then fix it up. 不要先创建一个int[]然后再对其进行修复。 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. 我强烈建议不要尝试使ToArrayOrNull正常工作的原因还在于,它甚至与您要说的应该做的事情ToArrayOrNull 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. 只要现在仍然不需要它,请暂时将其保留,以后再回头看时,您可能会突然看到它。

How about this using Cast<> and a type constraint making T a struct : 如何使用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();
}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM