当我编译以下两个代码时,它给出相同的结果(我想是这样)。
//ManagementObject :
SelectQuery query = new SelectQuery("Win32_Environment");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
foreach (ManagementObject envVar in searcher.Get())
Console.WriteLine("Variable : {0}, Value = {1}",envVar["Name"], envVar["VariableValue"]);
//ManagementBaseObject :
SelectQuery query = new SelectQuery("Win32_Environment");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
foreach (ManagementBaseObject envVar in searcher.Get())
Console.WriteLine("Variable : {0}, Value = {1}",envVar["Name"], envVar["VariableValue"]);
两个代码执行有什么区别......?
在这种特殊情况下,没有区别。
ManagementObjectSearcher.Get()
方法返回ManagementObjectCollection
,这是ManagementBaseObject
的集合。这意味着该集合可以包含ManagementBaseObject
类型的实例或任何来自ManagementBaseObject
的类型的实例。
但是,ManagementBaseObject
被设计为基类,这意味着实际上它不会被实例化,而是它的下行类将被实例化。请注意,这只是一种约定,并不是由语言或框架强制执行的。
另外,由于框架中(直接)继承ManagementBaseObject
的唯一类是ManagementObject
,因此Get()
有效地返回ManagementObject
实例的集合。请注意,这只是当前的情况,没有什么能阻止创建额外的ManagementBaseObject
继承者。
因此,对于所有提到的警告,这意味着,如果您仅使用在基类中定义的属性(而不是覆盖),则可以以任一方式迭代,并且代码将表现完全相同。在你的代码中,你只使用indexer类中确实定义的ManagementBaseObject
,而不是覆盖它。
如果你想要一个循环失败的代码示例,并且在另一个循环中工作,你可以尝试在ManagementObject
上定义的任何属性,例如,Path:
foreach (ManagementObject envVar in searcher.Get())
Console.WriteLine("Path : {0}, Value = {1}",envVar.Path.Path); //works
foreach (ManagementBaseObject envVar in searcher.Get())
Console.WriteLine("Path : {0}, Value = {1}",envVar.Path.Path); //compile error
你最好在这里使用ManagementBaseObject
。 Get()
方法返回一个(非泛型)ManagementObjectCollection
,其中包含ManagementBaseObject
派生类型,包括ManagementObject
和ManagementClass
。
第一个版本可能适用于您的特定查询,但通常您可能会收到无效的强制转换异常。
如果您只需要考虑ManagementObject
类型的对象,您可以考虑以下版本:
var query = new SelectQuery("Win32_Environment");
var searcher = new ManagementObjectSearcher(query);
foreach (var envVar in searcher.Get().OfType<ManagementObject>())
{
Console.WriteLine("Variable: {0}, Value = {1}",
envVar["Name"], envVar["VariableValue"]);
}