Search code examples
c#genericsclass-designobject-design

C# class design with Generic structure


This might be a simple one, but my head is refusing to wrap around that, so an outside view is always useful in that case!

I need to design an object hierarchy to implement a Parameter Registration for a patient. This will take place on a certain date and collect a number of different parameters about a patient (bloodpressure, heartrate etc). The values of those Parameter Registrations can be of different types, such as strings, integers, floats or even guids (for lookup lists).

So we have:

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: Thanks to the suggestions, the model has now morphed to the following:

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

which is indeed a bit simpler, but now I'm wondering, since the IList in ParameterRegistration points to the abstract ParameterRegistrationValue object, how will I be able to get the actual value out (since its stored on the sub-objects)?

Maybe the whole generic thing is indeed not quite the way to go after all :s


Solution

  • If you don't know the final set of parameter and the corresponding type of each parameter then the generics probably won't help - use object as a parameter value type.

    Furthermore iterating through the list of parameters will be a pain since you'll have to examine the type of each item in order to determine how to treat the value.

    What are you trying to achieve with generics ? Yes, they are cool (and going for boxing/unboxing is probably not a best idea), but in some cases you might want to use object instead (for both simplicity and flexibility).

    -- Pavel