Search code examples
c#oopclass-structure

C# Array Properties and Class Structure


The current structure of my classes goes a little bit like this: PC.Processor.Architecture[0] = The Architecture of the first processor (assuming a multi-processor system).

How I ideally want it is more like this: PC.Processor[0].Architecture, because it's a bit more self explanatory this way.

Is there a fairly efficient way of doing this with what I have? Bear in mind there are like, over 9000 properties in each of the classes Processor, Motherboard, Memory etc and WMI calls are not CPU-cheap to run.

Here are the important snippets for my classes

class PC
{
    public Processor Processor;
    public Motherboard Motherboard;

    // Constructor
    public PC()
    {
        Processor = new Processor();
        Motherboard = new Motherboard();
    }

    // Method to get all info sequentially
    public void GetAllInfo()
    {
        Processor.GetInfo();
        Motherboard.GetInfo();
    }
}

class Processor
{
    public string[] Architecture;
    public string[] Availability;
    public UInt16[] Cores;

    public void GetInfo()
    {
        // Get WMI Information from custom process
        // Returns as an array of ManagementObjects for each matched device (which is a bit like an array of dictionaries)
        ManagementObject[] WMIData = DataRetriever.GetWMIData("Win32_Processor");
        try
        {
            for (int i = 1; i < WMIData.Length; i++)
            {
                this.Architecture[i] = (string)WMIData[i]["Architecture"];
                this.Availability[i] = (string)WMIData[i]["Availability"];
                this.Cores[i] = (UInt16)WMIData[i]["NumberOfCores"];
            }
        }
        catch (NullReferenceException e)
        {
            // To be implemented
        }
    }
}

FURTHERMORE
There may be more than one WMI search query per class. For example, HardDrive needs to make use of both Win32_PhysicalMedia and ATAPI_SmartData (or whatever the class actually is.)


Solution

  • Thanks to everyone who's responded. I've come up with a reasonably elegant solution that suits my needs.

    PC Class Example:

    public class PC
    {
        public List<Processor> Processor;
    
        // Constructor
        public PC()
        {
            this.Processor = new List<Processor>();
        }
    
        // Method to get all info sequentially
        public void GetAllInfo()
        {
            // These temporary stores fetch WMI data as ManagementObjects
            // Most cases will only need one WMI class.
            ManagementObject[] WMIDataTemp1;
            ManagementObject[] WMIDataTemp2;
    
            WMIDataTemp1 = DataRetriever.GetWMIData("Win32_Processor");
            foreach (ManagementObject Object in WMIDataTemp1)
            {
                this.Processor.Add(new Processor(Object));
            }
        }
    
        public void RefreshAll()
        {
            // Delete the lists and start again
            // Another option would be to foreach through the list elements and initialise each object again.
            this.Processor.Clear();
            GetAllInfo();
        }
    
        public void RefreshVolatileData()
        {
            // Extra function that will do some cool stuff later.
        }
    }
    

    Processor Class Example:

    public class Processor
    {
        // Define properties
        public string Architecture = "N/A";
        public string Availability = "N/A";
        public UInt32 CacheL2 = 0;
        public UInt32 CacheL3 = 0;
    
        // Overloaded constructor method
        // The one with no arguments does nothing to initialise the class
        // The one with the ManagementObject argument will call GetInfo to arrange the held data into the properties above
        public Processor() { }
        public Processor(ManagementObject wmiProcessor)
        {
            this.GetInfo(wmiProcessor);
        }
    
        // The main information handler for the classes.
        // This splits out the data in the ManagementObject into the class's own properties
        public void GetInfo(ManagementObject wmiProcessor)
        {
            // If anything fails, the try loop will just end without making a fuss
            // Because of the default values, N/A will be displayed everywhere if something fails here.
            try
            {
                this.Architecture = (string)wmiProcessor["Architecture"];
                this.Availability = (string)wmiProcessor["Availability"];
                this.CacheL2 = (UInt32)wmiProcessor["L2CacheSize"];
                this.CacheL3 = (UInt32)wmiProcessor["L3CacheSize"];
            }
            catch (Exception e)
            {
    
            }
        }
    }
    

    Usage example:

    public PC Computer = new PC();
    Computer.GetAllInfo();
    textbox1.Text = Computer.Processor[0].Architecture
    

    In the event a device needs to query more than one WMI class, each additional class can be listed as an extra parameter in the device constructor and GetInfo() method.