为什么不让一个Processor
类只有单个属性Architecture
等Cores
并在其构造函数中获取一个ManagementObject
实例?然后,您可以从 的构造函数中的管理对象中提取所需的数据,并在您的对象中Processor
创建许多Processor
s 。PC
class PC
{
//I'd encapsulate these in a property rather than a public field
public Processor[] Processors;
public Motherboard Motherboard;
// Constructor
public PC()
{
Motherboard = new Motherboard();
}
// Method to get all info sequentially
public void GetAllInfo()
{
ManagementObject[] WMIData = DataRetriever.GetWMIData("Win32_Processor");
Processors = new Processor[WMIData.Length-1];
for (int i = 1; i < WMIData.Length; i++)
{
Processors[i-1] = new Processor(WMIData[i-1]); //assuming 0 based
}
Motherboard.GetInfo();
}
}
class Processor
{
public string Architecture;
public string Availability;
public UInt16 Cores;
public Processor(ManagementObject WMIData)
{
this.Architecture = (string)WMIData["Architecture"];
this.Availability = (string)WMIData["Availability"];
this.Cores = (UInt16)WMIData["NumberOfCores"];
}
}
如果您担心性能,那么您应该将公共字段隐藏在属性后面,然后在需要时懒惰地进行调用。显然,这是在需要时加载数据(可能涉及访问时的延迟)或预加载所有数据(这可能意味着开始时有延迟,但在需要时会很快)之间的权衡。所需的结果取决于您是否总是需要所有数据以及如何使用这些数据。
您可以将 WMIData 对象存储在处理器类中,并在访问属性时读取值。这取决于慢位的位置:
class Processor
{
private ManagementObject WMIData;
// obviously you might want to cache this value once it has been retrieved once
public string Architecture{get{return (string)WMIData["Architecture"];}}
public string Availability {get{return (string)WMIData["Availability"];}}
public UInt16 Cores{get{return (UInt16)WMIData["NumberOfCores"]}}
public Processor(ManagementObject WMIData)
{
this.WMIData = WMIData;
}
}
编辑
如果您需要超过 1 个 WMI 查询,则要么将每个 WMI 调用的结果传递给对象,以便它可以从中获取数据(听起来会很慢),要么给它足够的数据,以便它可以进行这些调用当它需要时:
class HardDrive
{
private int index;
private ManagmentObject physicalMediaInfo;
private ManagementObject smartDataInfo;
// choose one of these constructors. this one lets you delay all the WMI calls till you need to do them
public HardDrive(int index)
{
this.index=index;
}
//this one means you have to make the calls in advance
public HardDrive(ManagmentObject physicalMediaInfo,ManagementObject smartDataInfo)
{
this.physicalMediaInfo=physicalMediaInfo;
this.smartDataInfo=smartDataInfo;
}
private ManagementObject PhysicalMediaInfo
{
get
{
if(physicalMediaInfo==null)
{
ManagementObject[] WMIData = DataRetriever.GetWMIData("Win32_PhysicalMedia");
physicalMediaInfo=WMIData[index];
}
return physicalMediaInfo;
}
}
private ManagementObject SmartDataInfo
{
get
{
if(smartDataInfo==null)
{
ManagementObject[] WMIData = DataRetriever.GetWMIData("ATAPI_SmartData");
smartDataInfo=WMIData[index];
}
return smartDataInfo;
}
}
//property for getting the details of the hard disk
//uses the private property to ensure that the management object for the is only loaded when its needed
public int Sectors{get{return (int)PhysicalMediaInfo["Sectors"]};};
//Same for the smart data.
public int SomeSmartData{get{return (int)SmartDataInfo["SomeSmartData"]};};
}
这种方法允许您仅将每个 api 调用作为需要的属性来执行,并确保它只执行一次,而不管使用了多少属性。您可以组合构造函数并允许传入的管理对象为空,然后您可以提供用于查找的索引和未通过构造函数传入的 ManagementObject 实例,但让您可以自由传递一些 ManagementObjects如果它们可用或便宜,则可以预加载...
编辑 2
至于处理刷新,假设刷新需要确保下次访问数据时请求来自 APi 的最新信息,您应该能够简单地执行以下操作:
public void Refresh()
{
this.physicalMediaInfo=null;
this.smartDataInfo=null;
}
这意味着下次调用 Sectors 时,将从 WMIData 重新查询“Sectors”值,因为现有的 WMIObject 将被替换。