0

I have the following code:

public interface IParameter
{ 
   ParameterName Name { get; set; }
}

public interface IParameter<T> : IParameter
{
    T Value  { get; set; }
    T LLimit { get; }
    T RLimit { get; }
}

public class IntegerParameter : IParameter<int>
{
    public ParameterName Name { get; set; }

    public int Value  { get; set; }
    public int LLimit { get; private set; }
    public int RLimit { get; private set;}

    public IntegerParameter(ParameterName name, int value, int llimit, int rlimit)
    {
        Name   = name;
        Value  = value;
        LLimit = llimit;
        RLimit = rlimit;
    }
}

public class DoubleParameter : IParameter<double>
{
    public ParameterName Name { get; set; }

    public double Value  { get; set; }
    public double LLimit { get; private set; }
    public double RLimit { get; private set; }

    public DoubleParameter(ParameterName name, double value, double llimit, double rlimit)
    {
        Name   = name;
        Value  = value;
        LLimit = llimit;
        RLimit = rlimit;
    }
}

// ...

The code is part of a physics project I am putting together. Now here is my problem. I would like to be able to add the parameters in a dictionary based on the ParameterName but still be able to call the Value.

var A   = new IntegerParameter(ParameterName.X1, 10, 0, 100);
var B   = new DoubleParameter(ParameterName.X2, 56.4, 0, 78.6);
var set = new Dictionary<ParameterName,IParameter>();     

set.Add(A.Name, A);
set.Add(B.Name, B);

set[A.Name].Value; // I cannot do it since the Value is expressed only in the IParameter<T> part
ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199

1 Answers1

0

Wihtout changing your arcihtecture, (which would deserve an abstract base class, by the way) you can't mix int and doubles in the same list and hope to get an int or double.

You could use reflection, or

You could dot it this way (I think that quite a bad design, but it's just for the example), adding some more info in IParameter interface

With a base abstract class

public interface IParameter
    {
        ParameterName Name { get; set; }
        object GetValue();
        Type Type { get; }
    }

public interface IParameter<T> : IParameter where T : IConvertible
{
    T Value { get; set; }
    T LLimit { get; }
    T RLimit { get; }
}
public abstract class BaseParameter<T> : IParameter<T> where T : IConvertible
{
    protected BaseParameter(ParameterName name, T value, T llimit, T rlimit)
    {
        Name = name;
        Value = value;
        LLimit = llimit;
        RLimit = rlimit;
    }
    public ParameterName Name { get; set; }
    public object GetValue(){return Value;}
    public Type Type{get { return typeof(T); }}
    public T Value { get; set; }
    public T LLimit { get; private set; }
    public T RLimit { get; private set; }
}

public class IntegerParameter : BaseParameter<int>
{
    public IntegerParameter(ParameterName name, int value, int llimit, int rlimit)
        : base(name, value, llimit, rlimit)
    {
    }
}

public class DoubleParameter : BaseParameter<double>
{
    public DoubleParameter(ParameterName name, double value, double llimit, double rlimit)
        : base(name, value, llimit, rlimit)
    {
    }
}

Usage :

var a = new IntegerParameter(ParameterName.X1, 10, 0, 100);
var b = new DoubleParameter(ParameterName.X2, 56.4, 0, 78.6);
var set = new Dictionary<ParameterName, IParameter>();

set.Add(a.Name, a);
set.Add(b.Name, b);

//ouch, ugly, isn't it ?
var test = Convert.ChangeType(set[a.Name].GetValue(), set[a.Name].Type);
var k = test.GetType();//I'm an int
test = Convert.ChangeType(set[b.Name].GetValue(), set[b.Name].Type);
k = test.GetType();//I'm a double
Raphaël Althaus
  • 59,727
  • 6
  • 96
  • 122