• Advertisement
Sign in to follow this  

[.net] Converting strings to arbitrary types?

This topic is 4473 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Is there any way to programatically convert a string of data into an arbitrary type in .net? For example; I have a type that has an unspecified set of fields, which my system doesn't know about at design-time, seeing as how I'm dynamically creating types at run-time. Now I want to be able to deserialize string data into any dynamically created object (I've already looked at SOAPFormatter, but it will not work with what I'm doing; SOAP uses very strong naming of assemblies, my system does not use strong naming of assemblies at all, plus I need the ability to stream portions of data into a pre-existing object, and possibly transfer data between different types), but I've run into a problem. When I get a list of all the fields in a datatype, and I have the string data that I want to store into those fields, I don't see any easy way to convert that string into that type. I can use the Convert class, but that requires me to create a switch statement for each basic type, and doesn't allow me to expand my classes using non-basic datatypes. Basically, what I'm wondering is, why isn't there any .FromString() function, or conversion operator like in C++? And if there is, why can't I seem to find it? FieldInfo.SetValue() won't work for my purposes, by the way, since it cannot implicitly convert strings to numeric data types

Share this post


Link to post
Share on other sites
Advertisement
I'm not sure if this might help you, but have you looked into reflection? With Reflection you CAN convert things into their type based upon strings.

Note: I never used Reflection myself, but I've seen it can be used to convert strings to enums, so it's bound to work for dynamic created classes.

Toolmaker

Share this post


Link to post
Share on other sites
Have you taken a look at ComponentModel.TypeConverter? It is what the framework uses to drive the PropertyGrid control. A bit clunky for my tastes. Anyway I think it supports most of the primitive types and can convert them to and from strings. Other types you will probably have to deal with yourself -- or try to extend TypeConverter(use a custom type converter? -- whatever it is they want you do. I recall it being somewhat of a nightmare.)

If you want to use reflection you can cover the primitives by looking for a Parse or TryParse method via reflection (Why did they choose not to make an interface IParsable or somehting, I do not know) anyway, they all have these methods and the signatures are the same so you can use invoke on the MethodInfo or if you are concerned with speed do some Emitting (probably way beyond what you need).

see:
ComponentModel.TypeConverter
Type.GetMethod
MethodInfo.Invoke

One more thing: Some of the XML stuff seems to be able to do this -- for example XPathNavigator has a ValueAs method that does type conversion of course you may have already looked over the XML stuff if you were playing SOAP.


Hope this helps.

Share this post


Link to post
Share on other sites
I've done this with a class that surrounds a static Dictionary<type,delegate>, which automatically adds type.Parse for the primitives. Quite effective.

Share this post


Link to post
Share on other sites
Quote:
Original post by Telastyn
I've done this with a class that surrounds a static Dictionary<type,delegate>, which automatically adds type.Parse for the primitives. Quite effective.


Dynamic, easy to extend with custom parsing delegates should be reasonably fast. Very smart. How do you make your delegates? new Delegaete(type,methodName) or some other way? Do you invoke with DynamicInvoke or can you cast the delegates to an object Foo(string) form? Just interested. I have been playing with DynamicMethod and some other Emit stuff myself in a similar context. Trying avoid the heavy costs of reflection and still get some serious felxability.

Share this post


Link to post
Share on other sites
Let's see...

Simply object delegate(string). Requires the programmer to cast to, anon-delegate or otherwise specify that delegate type when adding to the class.

The main use for this class is in a quake-style console parser. The returned object is often stuffed into an object[] and passed to DynamicInvoke.

This was actually some of my first C# code, as I've a similar C++ serialization registry. It though uses template instantiation with static functors.

Share this post


Link to post
Share on other sites
You could try out XML Serialization as XML can be interpretted as a plain string. Although it's quite tricky to get into, it's a really handy tool. The only thing I don't like about it is that if something is not exactly right with the Schema, then it doesn't work. Here are some articles.

Share this post


Link to post
Share on other sites
C# has conversion operators (don't know about other .NET languages), but generating a static Parse() method for your dynamic types would be better. You can then use reflection to find the Parse() method for the type your trying to create (the reason for calling it Parse() is this will also work with the built-in types like System.Int32) and call it to create the instance. Something like this:


public static object FromString(Type type, string value)
{
// Find the Parse method
MethodInfo parser = type.GetField(type, BindingFlags.Static);
if(parser==null) throw new InvalidOperationException("No static Parse() method");

// Create the instance
return parser.Invoke(null, new object[] { value });
}




Your generated Parse() methods would parse the string and possibly call FromString as needed for creating instances for its fields.


EDIT: Hmmm, seems like I've just repeated part of what turnpast said [smile]

Share this post


Link to post
Share on other sites
turnpast is right - the proper way to do this is to write a TypeConverter and attach it to your class with the TypeConverter attribute. Then you can use Convert.ToXXX on your class just like you do on anything else.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement