почему бы не сделать класс Processor
просто имеющим отдельные свойства Architecture
, Cores
и т. Д. И взять экземпляр ManagementObject
в его конструкторе? Затем вы можете извлечь необходимые данные из объекта управления в конструкторе Processor
и просто создать множество Processor
в вашем 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 в классе Processor и просто читать значения при доступе к свойствам. Это зависит от того, где медленные биты:
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;
}
}
EDIT
если вам нужно более одного запроса 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;
}
Это будет означать, что в следующий раз, когда Секторы будут называться, значение "Секторы" будет запрашиваться из WMIData, поскольку существующий объект WMIO будет заменен.