【问题标题】:Correct way to boxing bool[] into object[] in C#在 C# 中将 bool[] 装箱到 object[] 的正确方法
【发布时间】:2014-03-26 00:37:58
【问题描述】:

我想找到在 C# .NET 4.0 中将 bool[] 转换为 object[] 的最佳方法。
现在我有了这个变量:

object[] objectArray  = new object [] { true, false, true };
string[] stringArray  = new string[]  { "true", "false", "true" };
bool[]   boolArray    = new bool[]    { true, false, true };

一切都很好。对于“明确类型”,例如 boolobjectboxing 可以正常工作 (object o = true;)。但在这种情况下,我只能从字符串数组转换为对象数组,而不能从布尔数组转换:

objectArray = stringArray; // OK 
objectArray = boolArray; // WRONG Cannot implicitly convert bool[] to object[]

此外,在某些方法中,我会发送对象数组列表。与之前的情况一样,我可以对字符串执行此(转换),但不能对布尔数组执行此操作:

List<object[]> testList;
testList = new List<object[]>() { objectArray }; // OK
testList = new List<object[]>() { stringArray }; // OK
testList = new List<object[]>() { boolArray };   // WRONG - I can not add bool[] into object[]

从一些方法中,我有一个布尔数组,里面有很多项目......最后一个方法,经过所有计算,返回一个对象数组作为结果(有时它必须返回其他类型,我不想拆分它变成了多种方法)。

然而,我不能使用return_object_array = boolean_array。这样做的最佳方法是什么?循环遍历布尔数组中的所有值并将其存储到对象数组中是最快的方式吗?

最好/最快/最正确的方法是什么?
注意:此方法是在 .NET 4.0 下编写的,但如果您知道 . NET 4.5 我想知道。

【问题讨论】:

  • boolaray.Select(x =&gt; (object)x).ToList();
  • 我认为这是一个 X/Y 问题 - 为什么要首先将布尔数组转换为对象数组?为什么该方法返回不同类型的数组?你为什么和List&lt;object[]&gt;一起工作?
  • 我不能使用泛型类型,因为创建了一些实现接口的方法(不是我的接口:))。但我知道使用泛型更好。
  • 它与string而不是bool一起工作的原因是string是一个引用类型,而.NET中的covariance特性只适用于引用类型.对于数组,string[] 也是 object[],因为 .NET 1 样式 数组协方差。这种协方差是“危险的”,因为数组不是只读的;每次您尝试编写对引用类型数组的新引用时,.NET 都会执行类型检查!使用接受IEnumerable&lt;&gt;List&lt;&gt; 的构造函数,它通过自.NET 4(2010 年,C# 4:interface IEnumerable&lt;out T&gt;)以来在泛型中引入的协方差来工作。
  • @Matt 一个简单的疏忽。你不必写那么长的评论来说明明显:)

标签: c# arrays object


【解决方案1】:

听起来您只需将每个值装箱,对吧?这很简单:

object[] objectArray = boolArray.Select(b => (object) b).ToArray();

甚至:

object[] objectArray = boolArray.Cast<object>().ToArray();

(作为Cast执行装箱/拆箱操作。)

或者在知道开始的正确尺寸方面更有效:

object[] objectArray = Array.ConvertAll(boolArray, b => (object) b);

或者,将您的 API 更改为需要object[] 才能开始。考虑改用泛型方法/类型。

编辑:为避免每次都装箱,您可以轻松编写自己的扩展类,类似于 nmclean 展示的框架:

public static class BooleanBoxExtensions
{
    private static readonly object BoxedTrue = true;
    private static readonly object BoxedFalse = false;

    public static object BoxCheaply(this bool value)
    {
        return value ? BoxedTrue : BoxedFalse;
    }
}

然后:

object[] objectArray = Array.ConvertAll(boolArray, b => b.BoxCheaply());

或者:

object[] objectArray = boolArray.Select(BooleanBoxExtensions.BoxCheaply)
                                .ToArray();

【讨论】:

  • 出于兴趣,您是否将 'b' 用于 lambda,因为该值是布尔值?
  • @Bobby 您可以使用任何字母或单词来表示 lambda,但有些人(包括我和 Jon Skeet)更喜欢使用与变量名称相关的字母。因此,对于boolArray,我将使用b,对于objectArray,我将使用o
  • 我经常走得更远,使用正确的名称。很多人对 lambda 的认识只是模糊的,一串串真的能激起恐惧,看到一个名字就可以减少一些。但是,对于像布尔数组这样的简单情况,附加值可能要小得多。
  • 或者如果需要object,至少缓存boxas the framework does
  • @nmclean:有没有等效于BooleanBoxes.Box的公共Framework方法?
【解决方案2】:
bool[] boolArray = { true, false, true };

var objArray = Array.ConvertAll(boolArray, x => (object)x);

【讨论】:

    【解决方案3】:

    Cast&lt;T&gt; 方法执行装箱。

    var castedValues = boolArray.Cast<object>();
    objectArray = castedValues.ToArray();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-18
      • 2012-06-10
      • 2020-10-10
      • 2022-06-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多