почему бы не сделать 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 в классе 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
, если вам нужно больше, чем 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 которые могут быть предварительно загружены, если они были доступны или дешево ...
EDIT 2
Что касается борьбы с обновлением, при условии, что обновления необходимо убедиться, что в следующий раз, данные доступ к последней информации от Апи испрашивается вы должны быть в состоянии просто сделать это:
public void Refresh()
{
this.physicalMediaInfo=null;
this.smartDataInfo=null;
}
Это означает, что в следующий раз, когда Sectors называется, значение «Sectors» будет повторно запрошено из WMIData, поскольку существующий WMIObject будет заменен.
Итак, один экземпляр класса Processor используется для представления N процессоров? Это похоже на проблему с дизайном. Позаботьтесь о том, чтобы объяснить это? Почему процессор не представляет собой один процессор? – Servy
@sll, о чем вы говорите? Прежде всего, список поддерживается массивом. Во-вторых, бокс/unboxing не встречается со ссылочными типами. –
В вашем классе ПК должна быть коллекция экземпляров Процессора, возможно, член под названием Процессоры (с s). Заполняйте свою коллекцию процессоров на ПК. Таким образом, вы можете достичь того, чего хотите: PC.Processors [0] .Cores – Tung