Frage

Dies mag einfach sein, aber mein Kopf weigert sich, sich darum zu wickeln, daher ist eine Außenansicht in diesem Fall immer nützlich!

Ich muss eine Objekthierarchie entwerfen, um eine Parameterregistrierung für einen Patienten zu implementieren. Dies erfolgt an einem bestimmten Datum und sammelt eine Reihe verschiedener Parameter über einen Patienten (Blutpressur, Herde usw.). Die Werte dieser Parameterregistrierungen können unterschiedliche Typen wie Zeichenfolgen, Ganzzahlen, Schwimmkörper oder sogar Guids sein (für Suchlisten).

Also haben wir:

public class ParameterRegistration
{
  public DateTime RegistrationDate { get; set; }
  public IList<ParameterRegistrationValue> ParameterRegistrationValues { get; set; }
}

public class ParameterRegistrationValue
{
  public Parameter Parameter { get; set; }
  public RegistrationValue RegistrationValue { get; set; }   // this needs to accomodate the different possible types of registrations!
}


 public class Parameter
  {
    // some general information about Parameters
  }

public class RegistrationValue<T>
{
  public RegistrationValue(T value)
  {
    Value = value;
  }

  public T Value { get; private set; }
}

AKTUALISIEREN: Dank der Vorschläge hat sich das Modell nun auf Folgendes verwandelt:

public class ParameterRegistration
{
  public DateTime RegistrationDate { get; set; }
  public IList<ParameterRegistrationValue> ParameterRegistrationValues { get; set; }
}

public abstract class ParameterRegistrationValue() 
{
  public static ParameterRegistrationValue CreateParameterRegistrationValue(ParameterType type)
{
    switch(type)
    {
        case ParameterType.Integer:
            return new ParameterRegistrationValue<Int32>();
        case ParameterType.String:
                return new ParameterRegistrationValue<String>();
        case ParameterType.Guid:
            return new ParameterRegistrationValue<Guid>();
        default: throw new ArgumentOutOfRangeException("Invalid ParameterType: " + type);
    }
}
  public Parameter Parameter { get; set; }
}

public class ParameterRegistrationValue<T> : ParameterRegistrationValue
{
  public T RegistrationValue {get; set; }
}

public enum ParameterType
{
  Integer,
  Guid,
  String
}

public class Parameter
{
  public string ParameterName { get; set; }
  public ParameterType ParameterType { get; set;}
}

Das ist in der Tat ein bisschen einfacher, aber jetzt frage ich mich, da der Ilist in Parameterregistrierung auf die zeigt abstrakt Parameterregistrierungsvalue-Objekt, wie kann ich den tatsächlichen Wert herausholen (da er auf den Sub-Objects gespeichert ist)?

Vielleicht ist das ganze generische Ding in der Tat nicht ganz der Weg: S.

War es hilfreich?

Lösung

Wenn Sie den endgültigen Parametersatz und den entsprechenden Typ jedes Parameters nicht kennen, wird die Generika wahrscheinlich nicht helfen. Verwenden Objekt als Parameterwerttyp.

Darüber hinaus ist die Iterierung der Parameterliste ein Schmerz, da Sie den Typ jedes Elements untersuchen müssen, um zu bestimmen, wie der Wert behandelt wird.

Was versuchen Sie mit Generika zu erreichen? Ja, sie sind cool (und das Boxen/Unboxen ist wahrscheinlich keine beste Idee), aber in einigen Fällen möchten Sie vielleicht verwenden Objekt Stattdessen (sowohl Einfachheit als auch Flexibilität).

- Pavel

Andere Tipps

Was Sie vielleicht vorstellen möchten, ist eine abstrakte Basisklasse für RegistrationValue<T> das ist nicht allgemein, so dass deine ParameterRegistrationValue Die Klasse kann eine nicht generische Referenz aufnehmen, ohne Kenntnis des beteiligten Typs zu benötigen. Alternativ kann es angemessen sein zu machen ParameterRegistrationValue generisches auch und fügen Sie stattdessen eine nicht generische Basisklasse hinzu (so dass die Werteliste in ParameterRegistration Kann von verschiedenen Typen sein.

1. Weg:

public abstract class RegistrationValue
{
}

public class RegistrationValue<T> : RegistrationValue
{
  public RegistrationValue(T value)
  {
    Value = value;
  }

  public T Value { get; private set; }
}

Und jetzt sollte Ihr Code kompilieren.


Sobald Sie eine nicht generische Basisklasse haben, würde ich auch Mitglieder der generischen Klasse verschieben, die nicht von den generischen Typparametern in diese Basisklasse abhängen. In diesem Beispiel gibt es keine, aber wenn wir stattdessen geändert haben ParameterRegistrationValue Um allgemein zu sein, würde ich mich bewegen Parameter in die nicht generische Basisklasse (weil sie nicht vom Typ Parameter für abhängt RegistrationValue)

Möglicherweise sollten Sie das öffentliche Registrierungswert für Registrierung verwenden, wobei t - Typ in Generic verwendet wird. Zum Beispiel ist T - String oder eine andere Klasse oder Struktur.

Oder Sie sollten die Parameterregistrierung von Klassen als generisches Vorsprung vornehmen, um generisches Argument im Feldregistrierungswert zu verwenden.

Ich glaube, Sie möchten eine Sammlung von Fällen von verschiedenen Fällen haben RegistrationValueS-abgeleitete Klassen und in der Lage sein, ihn zu iterieren und für jedes Element einen anderen Typ zu haben. Das ist ziemlich unmöglich.

Sie müssen immer noch jedes Element auf den Typ werfen, den Sie kennen, da die Sammlung die Verweise auf Ihren Basistyp zurückgibt (ParameterRegistrationValue - dieser angegeben von IList Typparameter). Es macht also keinen wirklichen Unterschied von der Iteration über Nichtgenerikat object aufführen.

Und wenn Sie dieses Casting für jeden Parameter sicher tun können (Sie kennen alle Typen), benötigen Sie wahrscheinlich überhaupt keine Sammlung - es ist besser, eine Klasse zu haben, die alle Parameter in einem Typ zusammenfasst. dass Sie es mit starken Typen, mit IntelliSense usw. nennen können: wie folgt:

public class ParameterRegistration
{
  public DateTime RegistrationDate { get; set; }
  public PatientData PatientData { get; set; }
  public Guid Identifier { get; set; }
  // ...
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top