Pregunta

Esto podría ser una simple, pero mi cabeza se niega a envolver alrededor de eso, así que una vista exterior es siempre útil en ese caso!

Me necesidad de diseñar una jerarquía de objetos para implementar un registro de parámetros para un paciente. Esto se llevará a cabo en una fecha determinada y recoger un número de diferentes parámetros de un paciente (presión sanguínea, frecuencia cardiaca, etc.). Los valores de dichos registros de parámetros pueden ser de diferentes tipos, tales como cadenas, enteros, flotadores o GUID incluso (para listas de búsqueda).

Así tenemos:

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

Actualizar : Gracias a las sugerencias, el modelo ahora se ha transformado a lo siguiente:

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

que en realidad es un poco más simple, pero ahora me pregunto, ya que el IList en puntos ParameterRegistration a la Extracto objeto ParameterRegistrationValue, ¿cómo voy a ser capaz de obtener el valor real a cabo (desde su almacenada en los sub-objetos)?

Tal vez todo el asunto genérico no es de hecho bastante el camino a seguir después de todo: s

¿Fue útil?

Solución

Si no se conoce el conjunto final de parámetros y el tipo correspondiente de cada parámetro a continuación, los genéricos probablemente no ayuda - uso objetivo como un tipo de valor de parámetro.

Por otra iteración a través de la lista de parámetros será difícil ya que tendrá que examinar el tipo de cada elemento con el fin de determinar cómo tratar el valor.

¿Qué está tratando de lograr con los genéricos? Sí, que son cool (y va para el boxeo / unboxing probablemente no es una mejor idea), pero en algunos casos es posible que desee utilizar objetivo en vez (por simplicidad y flexibilidad).

- Pavel

Otros consejos

What you might want to introduce is an abstract base class for RegistrationValue<T> that is not generic, so that your ParameterRegistrationValue class can hold a non-generic reference, without needing knowledge of the type involved. Alternatively, it may be appropriate to make ParameterRegistrationValue generic also, and then add a non-generic base class for it instead (so that the list of values in ParameterRegistration can be of different types.

1st way:

public abstract class RegistrationValue
{
}

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

  public T Value { get; private set; }
}

And now your code should compile.


Once you have a non-generic base class, I'd also move any members of the generic class that don't depend on the generic type parameters up into this base class. There aren't any in this example, but if we were instead modifying ParameterRegistrationValue to be generic, I'd move Parameter up into the non-generic base class (because it doesn't depend on the type parameter for RegistrationValue)

May be, you should use public RegistrationValue RegistrationValue, where T - is type, using in generic. For example, T - is String or other class or struct.

Or you should make class ParameterRegistrationValue as generic, to use generic argument in the field RegistrationValue.

I believe you want to have a collection of instances of different RegistrationValues-derived classes and be able to iterate it and for to have different type for each element. That's rather impossible.

You'll still need to cast each element to the type you know it is, because iterating the collection will return references to your base type (ParameterRegistrationValue - this one specified by IList type parameter). So it won't make any real difference from iterating over non-generic object list.

And if you can safely do that casting for each parameter (you know all the types), you probably don't need collection like this at all - it'll be better to have a class that encapsulates all the parameters in one type, so that you can call it with strong types, with IntelliSense etc. like this:

public class ParameterRegistration
{
  public DateTime RegistrationDate { get; set; }
  public PatientData PatientData { get; set; }
  public Guid Identifier { get; set; }
  // ...
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top