【问题标题】:How to convert type int[] to int?[]如何将类型 int[] 转换为 int?[]
【发布时间】:2016-03-12 15:54:39
【问题描述】:

我正在使用 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 传回可为空的类型?

【问题讨论】:

  • 您似乎在混合传递一个可为空的 int 数组与返回一个空数组。你想达到什么目的??
  • @PoweredByOrange where T : struct 完成这项工作。

标签: c# linq extension-methods ienumerable nullable


【解决方案1】:

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();

【讨论】:

    【解决方案2】:

    不要先做错事,然后再修复它。直接做正确的事。你知道你需要一个int?[]。所以创建一个int?[]。不要先创建int[],然后再修复它。你可以让它工作,但它毫无意义地复杂。

    int?[] vids1 = new[] { "", "1", "2", "3" }
        .Where(x => !String.IsNullOrWhiteSpace(x))
        .Select(x => (int?) Convert.ToInt32(x))
        .ToArray();
    

    我强烈建议不要尝试让你的ToArrayOrNull 工作的原因也是因为它甚至没有接近你所说的应该做的事情。你可以让它工作,但你必须在开始编码之前了解应该发生的事情。暂时不用它,等你以后再看时,你可能会突然看到它。

    【讨论】:

    • 我知道我忽略了一些东西。谢谢你让我直截了当。
    • @ooXei1sh 感谢您的编辑建议。我写了最后一句话,因为当我没有答案时重新阅读我的答案时,我觉得我有点像个混蛋。 :) 我很高兴你明白我的意思。
    【解决方案3】:

    此扩展方法ToArrayOrNull 不会更改内容的类型。 seqTIEnumerableresultT 的数组(您有时会返回为 null,但这仍然是 T 的数组。

    如果你真的想将IEnumerable&lt;T&gt;转换为IEnumerable&lt;T?&gt;(或T?的数组),你应该对类型参数施加一些约束(它应该是struct,意思是值类型,一个不能为空的),并转换每个项目而不是整个结果,例如:

        public static T?[] ToArrayOfNullable<T>(this IEnumerable<T> seq)
            where T : struct
        {
            return seq.Select(val => (T?)val).ToArray();
        }
    

    虽然我会在这里返回一个IEnumerable&lt;T?&gt; 并稍后转换为一个数组,以保持这个方法简单。

    【讨论】:

    • @M.kazemAkhgary,你说得对,我会改的。
    【解决方案4】:

    如何使用Cast&lt;&gt; 和类型约束使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();
    }
    

    【讨论】:

      【解决方案5】:

      我知道这不是您问题的正确答案,但有一些不同的解决方案 - 如果您想保持订单和收集长度。

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-05
        • 2020-10-22
        • 2018-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-21
        相关资源
        最近更新 更多