[英]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();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.