I have the following interface:
public interface IDynamicData: IPersistent
{
string Name { get; }
DataType Type { get; set; }
string InputFormat { get; set; }
dynamic Value { get; }
string DisplayValue { get; }
}
I have a couple of classes that implement this interface, but the one I am interested in is this one:
public class DynamicInput : IDynamicData
{
public string Name { get; private set; }
private DataType _Type;
public DataType Type
{
get { return _Type; }
set
{
_Type = value;
switch (Type)
{
case DataType.String:
Mapping = new StringMap();
break;
case DataType.Numeric:
Mapping = new DoubleMap();
break;
case DataType.DateTime:
Mapping = new DateTimeMap();
break;
default:
Mapping = new StringMap();
break;
}
}
}
[Browsable(false)]
public dynamic Value { get; private set; }
[Browsable(false)]
public string DisplayValue
{
get
{
return Value != null && (Type.Equals(DataType.DateTime) || Type.Equals(DataType.Numeric))
? Value.ToString(InputFormat)
: Value;
}
}
}
Now, the key here is the dynamic Value
property. This value is populated from a string input using the StringMap
, DecimalMap
, DoubleMap
and DateTimeMap
classes, where the key method is (similar) to this one:
public override dynamic ProcessInput(string input, int index, string inputFormat, double multiplier, char splitOn = ',')
{
_IsValid = false;
try
{
_Input = input;
double tmp;
_IsValid = Double.TryParse(input.Split(splitOn)[index], out tmp);
return tmp * multiplier;
}
catch
{
_IsValid = false;
return 0;
}
}
This seesm to work fine, and I effectively have a strongly typed Value
property at runtime (at least how I understand it). I would like to know when this definition of the type occurs though - when the object is instantiated, or when the Value
is assigned to.
I would like to be able to let the user change the type of the Value
property at runtime, which involves setting the DataType
property to either string
/DateTime
/double
etc. This however, sometimes results in a RuntimeBindingException
being thrown at runtime. It doesn't happen all the time, only sometimes, which, I am assuming occurs when the DataType
property is changed in between the Value
property being set and the DisplayText
property being read. That is where the error occurs, in this getter:
public string DisplayValue
{
get
{
return Value != null && (Type.Equals(DataType.DateTime) || Type.Equals(DataType.Numeric))
? Value.ToString(InputFormat)
: Value;
}
}
I would just like to understand why this happens, and if my analysis is correct, and potentially if there are any workarounds to this problem. If its not possible then thats fine, I will lock down editing of the type of the IDynamicData object.
EDIT
I have experienced this only once - hard to replicate. The instance was, the object was created with DataType.Numeric
. I had input strings like "12.345" coming in, every second and being parsed then assigned to the Value
property. Then, while I am still receiving data, I changed to DataType.String
. This is where the exception occurred. That is, DoubleMap
was returning a "dynamic" double
, then while input data is still coming in, the StringMap
returned a "dynamic" string
representation of `12.345'.