此代码可以正常工作:
Process v = Process.GetProcessById(6752); // firefox
Console.WriteLine(v);
ProcessThreadCollection th = v.Threads;
foreach (ProcessThread pt in th)
{
var info = string.Format("-> Thread ID: {0}\tStart Time: {1}\tPriority: {2}",
pt.Id, pt.StartTime.ToShortTimeString(), pt.PriorityLevel);
Console.WriteLine(info);
}
但是不要这样做:
Process v = Process.GetProcessById(6752); // firefox
Console.WriteLine(v);
ProcessThreadCollection th = v.Threads;
foreach (var pt in th) // var instead of ProcessThread
{
var info = string.Format("-> Thread ID: {0}\tStart Time: {1}\tPriority: {2}",
pt.Id, pt.StartTime.ToShortTimeString(), pt.PriorityLevel);
Console.WriteLine(info);
}
第二个 pt
由编译器假定为object
,当然不编译。
为什么编译器将ProcessThreadCollection
的元素假定为object
而不是ProcessThread
?
答案 0 :(得分:9)
Process.Threads
是IEnumerable
,而不是IEnumerable<ProcessThread>
。第一个代码段中的代码是将IEnumerable
中的每个对象投射到ProcessThread
。您的第二个代码段中的代码根本不会转换代码,而是使用对象的实际类型,即object
。
答案 1 :(得分:4)
ProcessThreadCollection
的调查员来自ReadOnlyCollectionBase
,其调查员为IEnumerator
而不是IEnumerator<ProcessThread>
。
GetEnumerator
中的 ReadOnlyBaseCollection
是一个虚方法,默认情况下返回this.InnerList.GetEnumerator()
- InnerList是ArrayList
。 ProcessThreadCollection
不会覆盖此方法,这就是您获取对象而不是ProcessThread
的原因。
对此的最佳解决方案是(我确信你知道)只需这样做:
foreach(ProcessThread pt in th)