4

I have a a sql table with 2 columns, excluding PK, etc


 DataType                  Value
 --------------------------------------
 System.String             Demo
 System.Int32              23
 System.Decimal            184,54
 System.DateTime           2018-04-25 08:57:27.6305273

How can I parse dynamically the value from the Value column, as the type specified in the DataType column. There can also be different data types: bool, double, etc (Always standard ones. No customs data type so I don't need to fetch assemblies etc)

Of course I can have a dumb solution like:

 object value;

 if (DataType == "System.String")
 {
     value = Convert.ToString(XXXX);
 }

is there a better generic approach to parse this dynamically?

EDIT:

What do you guys think of this? Is it an overkill ?

Type oType = Type.GetType("System.String");

using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(VALUE_IN_HERE)))
{
    stream.Seek(0, SeekOriginal.Begin);
    var dcs = new DataContractSerializer(oType);
    return dcs.ReadObject(stream);
}
user2818430
  • 5,853
  • 21
  • 82
  • 148
  • 1
    Sure, don't store the type in a column but provide one column for each value-type, Then you can use `reader.GetString(..)`,`reader.GetInt32(..)`,`reader.GetDecimal(..)`, `reader.GetDateTime(..)` – Tim Schmelter Sep 20 '18 at 15:23
  • 1
    create `Type` object by name https://stackoverflow.com/questions/223952/create-an-instance-of-a-class-from-a-string and execute `Convert.ChangeType` https://learn.microsoft.com/ru-ru/dotnet/api/system.convert.changetype?redirectedfrom=MSDN&view=netframework-4.7.2#System_Convert_ChangeType_System_Object_System_Type_ – Dmitry Pavliv Sep 20 '18 at 15:23
  • What type has the `Value`-column in the database at all? – Tim Schmelter Sep 20 '18 at 15:26
  • @TimSchmelter: nvarchar both – user2818430 Sep 20 '18 at 15:29
  • Seams Hanselman has a nice solution: http://www.hanselman.com/blog/TypeConvertersTheresNotEnoughTypeDescripterGetConverterInTheWorld.aspx – user2818430 Sep 20 '18 at 15:32
  • Even with the Typeconverter, you will have to build something, that decides, which one to convert to... but they are nice. – Andreas Sep 20 '18 at 15:53

3 Answers3

4

Storing data types seems like an anti-pattern but you could do something like:

Type t = Type.GetType(DataType);
value = Convert.ChangeType(XXXX, t);
Parrish Husband
  • 3,148
  • 18
  • 40
  • @Fabjan yes per OP's declaration of `value`. `dynamic value = `... could be better, but I honestly think this is just a band-aid on a wounded code base. – Parrish Husband Sep 20 '18 at 16:01
  • Whoops, sorry the `value` is actually of type `object`, then it's a good answer – Fabjan Sep 20 '18 at 16:02
0

First: Don't get the String output, use a datareader if possible, a Linq Mapping or EntityFramework to access the colums.

Second: You could do it with a Factory ... or some sort of in the lack of a better name.

Dictionary<String,Func<String,object>> factory

add your methods that create the type and return it to the dictionary

factory["System.String"] = (s) => s;
factory["System.Int32"] (i) => Int32.Parse(i);

make it, that you have the type and the value in two variables and just execute

object val = factory[type](value);

You still dont have the type info, but you could go one step further:

Dictionary<String, Action<String>> factory;
factory["System.Int32"] = i => DoSomethingGeneric(Int32.Parse(i));
factory["System.String"] = s => DoSomethingGeneric(s);

private void DoSomethingGeneric<T>(T value)
{
  at least you have a type here and can do something with it
}

Still not very useful, but you mentioned generic(s).If you are willing to handle the values independently you could use this approach:

Dictionary<String, Action<String>> factory;
factory["System.Int32"] = i => DoSomethingWithInt(Int32.Parse(i));
factory["System.String"] = s => DoSomethingWithStrings(s);
Andreas
  • 828
  • 4
  • 15
0
Type foo = typeof(data);

will return you the parsed type, even if you inherited data with type object.

Fabi
  • 199
  • 1
  • 14