简体   繁体   English

为什么不能将DateTime []强制转换为object []?

[英]Why can't I cast DateTime[] to object[]?

It seems that I can cast DateTime to object, so why can't I cast array DateTime[] to object[]? 看来我可以将DateTime强制转换为对象,所以为什么不能将数组DateTime []强制强制转换为object []? I know this has something to do with value/reference types, but doesn't boxing allow me to do this? 我知道这与值/引用类型有关,但是装箱不允许我这样做吗?

Array covariance only applies to arrays of reference types. 数组协方差仅适用于引用类型的数组。 DateTime is a value type so you can't assign a DateTime[] to an object[] variable. DateTime是一种值类型,因此您无法将DateTime[]分配给object[]变量。 You'll have to explicitly create an object array and copy the values over. 您必须显式创建一个对象数组并将其值复制过来。 In other words, create a new array instance of type object[] . 换句话说,创建一个类型为object[]的新数组实例。

There are plenty of ways you can do this. 有很多方法可以做到这一点。 A simple use of CopyTo() should be enough. 简单地使用CopyTo()就足够了。

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

I ran some tests. 我进行了一些测试。 Probably not the best way to do it but it should give a good idea of what it would be with a proper profiler. 可能不是执行此操作的最佳方法,但应该可以很好地了解使用适当的探查器的情况。

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

Specs: 眼镜:
Win7Pro x64, Core2Quad Q9550@2.83GHz, 4GiB DDR2 1066 (PC2-8500) Win7Pro x64,Core2Quad Q9550 @ 2.83GHz,4GiB DDR2 1066(PC2-8500)
64-bit build (32-bit is roughly the same, just less memory overall) 64位版本(32位大致相同,总体内存较少)

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

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

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

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

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

Interestingly, ConvertAll() performs much the same as a plain loop. 有趣的是, ConvertAll()执行与普通循环几乎相同。

You can't cast DateTime[] to object[] because it would be unsafe. 您不能将DateTime[]object[]因为这是不安全的。 All arrays of reference types of the same length have the same layout in memory. 相同长度的引用类型的所有数组在内存中的布局均相同。 DateTime is value type, and the array is "flat" (unboxed). DateTime是值类型,并且数组是“ flat”(未装箱)。 You can't safely cast to object[] because the layout in memory is incompatible with object[] . 您不能安全地强制转换为object[]因为内存中的布局与object[]不兼容。

If you've got LINQ available (.NET 3.5+) you can do: 如果您可以使用LINQ(.NET 3.5+),则可以执行以下操作:

DateTime[] dates = new DateTime[3];

dates[0] = new DateTime(2009, 01, 01);
dates[1] = new DateTime(2010, 01, 01);
dates[2] = new DateTime(2011, 01, 01);

object[] dates2 = Array.ConvertAll(dates, d => (object)d);

As Jeff pointed out you can also do a similar thing in .NET 2.0 using delegates: 正如Jeff指出的那样,您还可以使用委托在.NET 2.0中执行类似的操作:

object[] dates3 = Array.ConvertAll(dates, 
                        delegate(DateTime d) { return (object)d; });

BTW, you can accomplish this using Array.Copy() 顺便说一句,您可以使用Array.Copy()完成此操作

void Main()
{
    DateTime[] dates = new DateTime[] { new DateTime(2000, 1, 1), new DateTime (2000, 3, 25) };
    object[] objDates = new object[2];
    Array.Copy(dates, objDates, 2);

    foreach (object o in objDates) {
        Console.WriteLine(o);
    }
}

Because DateTime is an object , but an array of DateTime isn't an array of object . 因为DateTime 一个object ,但是DateTime的数组不是 object的数组。

Arrays of value types are different than arrays of reference types so these two types of arrays are fundamentally incompatible. 值类型的数组与引用类型的数组不同,因此这两种类型的数组在根本上是不兼容的。 The value type array actually contains the values and the reference type array contains, well, only references. 值类型数组实际上包含值,而引用类型数组仅包含引用。

See the other answers for why you cannot do so. 有关无法执行操作的原因,请参见其他答案。

The alternative is to perform a deep copy of the array. 另一种方法是执行阵列的深层复制。 Example using LINQ: 使用LINQ的示例:

DateTime[] dates = ...;
object[] objects = dates.Select(d => (object)d).ToArray();

为什么我不能从列表中投射<myclass>列出<object> ?<div id="text_translate"><p> 我有一个对象列表,它们属于我的QuoteHeader类型,我想将此列表作为对象列表传递给能够接受List&lt;object&gt;的方法。</p><p> 我的代码行显示...</p><pre> Tools.MyMethod((List&lt;object&gt;)MyListOfQuoteHeaders);</pre><p> 但是我在设计时收到以下错误...</p><pre> Cannot convert type 'System.Collections.Generic.List&lt;MyNameSpace.QuoteHeader&gt;' to 'System.Collections.Generic.List&lt;object&gt;'</pre><p> 我需要对我的 class 做任何事情来允许这样做吗? 我认为所有类都继承自 object 所以我不明白为什么这不起作用?</p></div></object></myclass> - Why can't I cast from a List<MyClass> to List<object>?

暂无
暂无

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

相关问题 为什么我不能将int强制转换为T,但可以将int强制转换为对象,然后又反对为T? - Why can't I cast int to T, but can cast int to object and then object to T? 为什么我不能投射EntityCollection <TEntity> 到ICollection <Object> ? - Why can't I cast EntityCollection<TEntity> to ICollection<Object>? 为什么我不能将对象强制转换为约束泛型? - Why can't I cast an object to a constrained generic? 为什么不能将long的对象变量转换为double? - Why can't I cast an object-var of a long to a double? 为什么我不能隐式地将此对象强制转换为类引用 - Why can't I implicitly cast this object to a class reference 为什么我不能从列表中投射<myclass>列出<object> ?<div id="text_translate"><p> 我有一个对象列表,它们属于我的QuoteHeader类型,我想将此列表作为对象列表传递给能够接受List&lt;object&gt;的方法。</p><p> 我的代码行显示...</p><pre> Tools.MyMethod((List&lt;object&gt;)MyListOfQuoteHeaders);</pre><p> 但是我在设计时收到以下错误...</p><pre> Cannot convert type 'System.Collections.Generic.List&lt;MyNameSpace.QuoteHeader&gt;' to 'System.Collections.Generic.List&lt;object&gt;'</pre><p> 我需要对我的 class 做任何事情来允许这样做吗? 我认为所有类都继承自 object 所以我不明白为什么这不起作用?</p></div></object></myclass> - Why can't I cast from a List<MyClass> to List<object>? 为什么我不能将双重对象转换为字节? - Why can I not cast a double object to a byte? 为什么我不能在C#中另一个类的DateTime对象上调用DateTime方法 - Why can't I call a DateTime method on a DateTime object in another class in C# 为什么不能将`this`转换为泛型? - Why can't I cast `this` to a generic type? 为什么我不能转换ref参数? - Why can't I cast a ref parameter?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM