2017-07-27 2 views
0

Ich suche einen Weg, ein Wörterbuch zu erstellen, das mehrere Klassen als Wert akzeptiert.C# -Wörterbuch mehrere Klassen als Werte

Ich bekomme Wert von Xiaomi Gateway und foreach Art von Ausrüstung, ich habe Klasse für jede Art von Ausrüstung.

Zum Beispiel meines Magnetsensor:

[XiaomiEquipement("magnet")] 
public class Magnet 
{ 
    public string Model { get; set; } = "magnet"; 
    public string Sid { get; set; } 
    public string Battery { get; set; } = "CR1632"; 
    public int BatteryLevel { get; set; } 
    public MagnetReport Report { get; set; } 
} 

[XiaomiEquipement("magnet_report")] 
public class MagnetReport 
{ 
    public int Voltage { get; set; } 
    public status { get; set; } 
} 

Und mein Stecker-:

[XiaomiEquipement("plug")] 
public class Plug 
{ 
    public string Model { get; set; } = "plug"; 
    public string Sid { get; set; } 
    public string Battery { get; set; } = "CR2450"; 
    public int BatteryLevel { get; set; } 
    public PlugReport Report { get; set; } 
} 

[XiaomiEquipement("plug_report")] 
public class PlugReport 
{ 
    public int Voltage { get; set; } 
    public string Status { get; set; }  
} 

Xiaomi Gateway zwei Arten von Daten senden, berichten, wenn etwas passieren und alle x Minuten Herzschlag.

{ "cmd": "Herzschlag", "Modell": "Stecker", "sid": "158d000123f0c9", "short_id": 11119, "data": "{\" voltage \ ": 3600 , "Status": "Aus", "Inuse": "0", "power_consumed": "7", "load_power": "0,00" }

{"cmd": "Bericht", "Modell": "plug", "sid": "158d000123f0c9", "short_id": 11119, "Daten": "{\" Status \ ": \" on \ "}"}

Wie Sie sehen können, haben die zwei Zeilen nicht die gleichen Daten. Ich möchte also die Plug-Klasse initialisieren und die fehlenden Daten füllen, wenn Heartbeat oder Report eintrifft.

Ich benutze Activator.CreateInstance mit dem Sensortyp, um die richtige Klasse zu erstellen.

modelType = Assembly.GetExecutingAssembly().GetTypes().SingleOrDefault(t => t.GetCustomAttribute<Response.XiaomiEquipementAttribute>()?.Model == read.Model); 
modelReportType = Assembly.GetExecutingAssembly().GetTypes().SingleOrDefault(t => t.GetCustomAttribute<Response.XiaomiEquipementAttribute>()?.Model == read.Model + "_report"); 

Ich versuche Wörterbuch zu verwenden, um meine Sensordaten zu speichern, dann nach en Herzschlag bearbeiten, aber es funktioniert nicht wie jeder Sensor eine andere Klasse.

Ich versuche, eine Schnittstelle hinzuzufügen, es funktioniert, aber es funktioniert nicht für Berichtsklasse.

Wie kann ich diese Klassen in mein Wörterbuch aufnehmen und darauf zugreifen?

Grundsätzlich möchte ich in das Wörterbuch nach Schlüssel suchen, Wert erhalten und einen Teil davon ändern.

+0

Haben Sie versucht, abstrakte Klassen zu verwenden? – noone392

+0

Oder eine Schnittstelle? –

+2

Auch wenn Sie wollen, dass es alles sein kann, können Sie nur das Werttyp-Objekt machen, dann, wenn Sie feststellen, welchen Typ es ist, rufen Sie einfach das object.type() und – noone392

Antwort

1

Sie können eine Dictionary<string, object> verwenden, um sie zu speichern.

var items = new Dictionary<string, object>(); 
var mag = new Magnet() { Sid = "1" }; 
var mot = new Motion() { Sid = "2" }; 
items.Add(mag.Sid, new Magnet()); 
items.Add(mot.Sid, new Motion()); 

Dann können Sie die Art bestimmen Object.GetType() wie folgt aus:

foreach (var thisItem in items) 
{ 
    // or use thisItem.Value is Magnet 
    if (thisItem.Value.GetType().Name == "Magnet") 
    { 
     Console.WriteLine("Magnet"); 
    } 
    else 
    { 
     Console.WriteLine("Motion"); 
    } 
} 

Sie auch die gemeinsamen Eigenschaften in einer Basisklasse stellen können und die beiden Klassen von der Basisklasse erben.

+0

Ein guter Name für die Basisklasse wäre * Sensor *: o) –

+1

Ich würde 'if (thisItem.Value ist Magnet Magnet)' –

+0

@KrisVandermotten thanks! Das ist ein guter Vorschlag. Eigentlich ist es besser. – CodingYoshi

Verwandte Themen