【问题标题】:What is the difference between ManagementObject and ManagementBaseObjectManagementObject 和 ManagementBaseObject 有什么区别
【发布时间】:2013-01-29 12:09:35
【问题描述】:

当我编译以下两个代码时,它给出了相同的结果(我认为是这样)。

//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"]);

这两种代码执行有什么区别...?

【问题讨论】:

    标签: .net wmi wql


    【解决方案1】:

    在这种特殊情况下,没有区别。

    ManagementObjectSearcher.Get() 方法返回一个ManagementObjectCollection,它是ManagementBaseObject 的集合。这意味着集合可以包含ManagementBaseObject 类型的实例或ManagementBaseObject 的任何派生类型的实例。

    但是,ManagementBaseObject 被设计为基类,这意味着实际上它不会被实例化,而是它的后代类将被实例化。请注意,这只是一个约定,并非由语言或框架强制执行。

    此外,由于框架中(直接)继承ManagementBaseObject 的唯一类是ManagementObjectGet() 有效地返回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
    

    【讨论】:

    • 但是请注意,使用ManagementObject 的第一个版本之所以有效,只是因为目前没有从ManagementBaseObject 派生的其他类型。 Get() 方法的契约没有任何保证。
    • 添加了更强有力的措辞来强调这一事实。虽然我怀疑这些类的设计是否会改变(它们一直在 for a long time 附近),但使用此代码意味着依赖于未经证实和不受支持的假设。
    【解决方案2】:

    您最好在此处使用ManagementBaseObjectGet() 方法返回一个(非泛型)ManagementObjectCollection,其中包含ManagementBaseObject 派生类型,包括ManagementObjectManagementClass

    第一个版本可能适用于您的特定查询,但通常您可能会遇到无效的强制转换异常。

    如果您只需要考虑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"]);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-24
      • 2010-10-02
      • 2011-12-12
      • 2010-09-16
      • 2012-03-14
      • 2012-02-06
      • 2011-02-25
      • 2011-11-22
      相关资源
      最近更新 更多