Question

Cela peut être simple, mais ma tête refuse de s'enrouler autour de cela, donc une vue à l'extérieur est toujours utile dans ce cas!

Je dois concevoir une hiérarchie d'objets pour mettre en œuvre un enregistrement de paramètre pour un patient. Cela aura lieu à une date et de recueillir un certain nombre de paramètres différents d'un patient (bloodpressure, fréquence cardiaque, etc.). Les valeurs de ces enregistrements paramètres peuvent être de différents types, tels que des chaînes, des entiers, des flotteurs ou même (pour les listes GUIDs de consultation).

Nous avons donc:

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; }
}

UPDATE : Merci aux suggestions, le modèle a mué à ce qui suit:

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;}
}

qui est en effet un peu plus simple, mais maintenant je me demande, puisque le IList points ParameterRegistration au abstrait objet ParameterRegistrationValue, comment vais-je être en mesure d'obtenir la valeur réelle sur (depuis sa stockés sur les sous-objets)?

Peut-être que toute chose générique est en effet pas tout à fait le chemin à parcourir après tout: s

Était-ce utile?

La solution

Si vous ne connaissez pas le dernier jeu de paramètres et le type correspondant de chaque paramètre alors les médicaments génériques ne sera probablement pas d'aide - utiliser l'objet comme type de valeur de paramètre.

En outre itérer la liste des paramètres sera une douleur puisque vous devrez examiner le type de chaque élément afin de déterminer comment traiter la valeur.

Qu'est-ce que vous essayez d'atteindre avec les génériques? Oui, ils sont cool (et aller pour la boxe / unboxing est probablement pas une meilleure idée), mais dans certains cas, vous pouvez utiliser objet au lieu (pour la simplicité et la flexibilité).

- Pavel

Autres conseils

Ce que vous voudrez peut-être présenter est une classe de base abstraite pour RegistrationValue<T> qui n'est pas générique, de sorte que votre classe ParameterRegistrationValue peut contenir une référence non générique, sans avoir besoin de connaissances du type concerné. Sinon, il peut être approprié de faire ParameterRegistrationValue aussi générique, puis ajoutez une classe de base non générique au lieu (de sorte que la liste des valeurs ParameterRegistration peut être de différents types.

1er chemin:

public abstract class RegistrationValue
{
}

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

  public T Value { get; private set; }
}

Et maintenant, votre code devrait compiler.


Une fois que vous avez une classe de base non générique, je voudrais également déplacer les membres de la classe générique qui ne dépendent pas des paramètres de type générique vers le haut dans cette classe de base. Il n'y en a pas dans cet exemple, mais si nous étions à la place modifions ParameterRegistrationValue être générique, je passerions Parameter vers le haut dans la classe de base non générique (car il ne dépend pas du type de paramètre pour RegistrationValue)

Peut-être, vous devez utiliser RegistrationValue publique RegistrationValue, où T - est de type, en utilisant dans générique. Par exemple, T - est une chaîne ou une autre classe ou struct.

Ou vous devez faire classe ParameterRegistrationValue comme générique, d'utiliser l'argument générique dans le RegistrationValue sur le terrain.

Je crois que vous voulez avoir une collection d'instances de différentes classes dérivées RegistrationValues et être en mesure de itérer et pour avoir différents types pour chaque élément. C'est plutôt impossible.

Vous aurez toujours besoin de jeter chaque élément du type vous savez qu'il est, parce que itérer la collection renvoie des références à votre type de base (ParameterRegistrationValue - celui défini par le paramètre type IList). Donc, il ne fera aucune différence réelle de itérer liste object sur non générique.

Et si vous pouvez faire en toute sécurité que la coulée pour chaque paramètre (vous connaissez tous les types), vous avez probablement le faire à pas besoin de collection comme tout - il sera préférable d'avoir une classe qui encapsule tous les paramètres dans un tapez, de sorte que vous pouvez l'appeler avec des types forts, avec IntelliSense etc. comme ceci:

public class ParameterRegistration
{
  public DateTime RegistrationDate { get; set; }
  public PatientData PatientData { get; set; }
  public Guid Identifier { get; set; }
  // ...
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top