看来我可以将DateTime强制转换为对象,所以为什么不能将数组DateTime []强制强制转换为object []?我知道这与值/引用类型有关,但是装箱不允许我这样做吗?

最佳答案

Array covariance仅适用于引用类型的数组。 DateTime是一种值类型,因此您无法将DateTime[]分配给object[]变量。您必须显式创建一个对象数组并将其值复制过来。换句话说,创建一个类型为object[]的新数组实例。

有很多方法可以做到这一点。只需简单地使用 CopyTo() 就足够了。

DateTime[] x = new DateTime[] { ... };
object[] y = new object[x.Length];
x.CopyTo(y, 0);

我进行了一些测试。可能不是执行此操作的最佳方法,但是应该可以很好地了解使用适当的探查器的情况。
class Program
{
    static void Main(string[] args)
    {
        var now = DateTime.Now;
        var dates = new DateTime[5000000];
        for (int i = 0; i < dates.Length; i++)
            dates[i] = now.AddSeconds(i);
        for (int i = 0; i < 5; i++)
        {
            Test("Test1", () =>
            {
                var result = new object[dates.LongLength];
                for (long l = 0; l < result.LongLength; l++)
                    result[l] = dates[l];
                return result;
            });
            Test("Test2", () =>
            {
                var result = new object[dates.LongLength];
                dates.CopyTo(result, 0);
                return result;
            });
            Test("Test3", () =>
            {
                var result = new object[dates.LongLength];
                Array.Copy(dates, result, dates.LongLength);
                return result;
            });
            Test("Test4", () =>
            {
                var result = Array.ConvertAll(dates, d => (object)d);
                return result;
            });
            Test("Test5", () =>
            {
                var result = dates.Cast<object>().ToArray();
                return result;
            });
            Test("Test6", () =>
            {
                var result = dates.Select(d => (object)d).ToArray();
                return result;
            });
            Console.WriteLine();
        }
    }

    static void Test<T>(string name, Func<T> fn)
    {
        var startMem = GC.GetTotalMemory(true);
        var sw = Stopwatch.StartNew();
        var result = fn();
        sw.Stop();
        var endMem = GC.GetTotalMemory(false);
        var diff = endMem - startMem;
        Console.WriteLine("{0}\tMem: {1,7}/{2,7} ({3,7})", name, startMem, endMem, diff);
        Console.WriteLine("\tTime: {0,7} ({1,7})", sw.ElapsedMilliseconds, sw.ElapsedTicks);
    }
}

眼镜:
Win7Pro x64,Core2Quad Q9550 @ 2.83GHz,4GiB DDR2 1066(PC2-8500)
64位版本(32位大致相同,总体内存更少)

Test1内存:40086256/200087360(160001104)
时间:444(1230723)
Test2内存:40091352/200099272(160007920)
时间:751(2078001)
Test3内存:40091416/200099256(160007840)
时间:800(2213764)
Test4内存:40091480/200099256(160007776)
时间:490(1358326)
Test5内存:40091608/300762328(260670720)
时间:1407(3893922)
Test6内存:40091672/300762328(260670656)
时间:756(2092566)

Test1内存:40091736/200099184(160007448)
时间:515(1425098)
Test2内存:40091736/200099184(160007448)
时间:868(2404151)
Test3内存:40091736/200099160(160007424)
时间:885(2448850)
Test4内存:40091736/200099184(160007448)
时间:540(1494429)
Test5内存:40091736/300762240(260670504)
时间:1479(4093676)
Test6内存:40091736/300762216(260670480)
时间:746(2065095)

Test1内存:40091736/200099168(160007432)
时间:500(1383656)
Test2内存:40091736/200099160(160007424)
时间:781(2162711)
Test3内存:40091736/200099176(160007440)
时间:793(2194605)
Test4内存:40091736/200099184(160007448)
时间:486(1346549)
Test5内存:40091736/300762232(260670496)
时间:1448(4008145)
Test6内存:40091736/300762232(260670496)
时间:749(2075019)

Test1内存:40091736/200099184(160007448)
时间:487(1349320)
Test2内存:40091736/200099176(160007440)
时间:781(2162729)
Test3内存:40091736/200099184(160007448)
时间:800(2214766)
Test4内存:40091736/200099184(160007448)
时间:506(1400698)
Test5内存:40091736/300762224(260670488)
时间:1436(3975880)
Test6内存:40091736/300762232(260670496)
时间:743(2058002)

Test1内存:40091736/200099184(160007448)
时间:482(1335709)
Test2内存:40091736/200099184(160007448)
时间:777(2150719)
Test3内存:40091736/200099184(160007448)
时间:793(2196184)
Test4内存:40091736/200099184(160007448)
时间:493(1365222)
Test5内存:40091736/300762240(260670504)
时间:1434(3969530)
Test6内存:40091736/300762232(260670496)
时间:746(2064278)

有趣的是,ConvertAll()的执行与普通循环几乎相同。

关于c# - 为什么不能将DateTime []强制转换为object []?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6024709/

10-09 09:31