user2354274
user2354274

Reputation: 187

Change data type dynamically in c#

I want to convert the data type dynamically.

My code:

private static void updateValues(SqlDataReader reader)  
{
        USR_AddressItem item = new USR_AddressItem();
        Type ConvertNewType;
        ConvertNewType = Type.GetType(item.UserId.GetType().Name);
        item.UserId = (ConvertNewType)(reader[UserDAL.USR_Address.FieldNames.UserId]);

}

Here data type only in dynamically. Because I want to assign value this variable in run time. I will get values from SqlDataReader. This reader return always string values. I am going to use this method globally.

Upvotes: 7

Views: 9458

Answers (3)

Adrian Salazar
Adrian Salazar

Reputation: 5319

Well, what you need is called type inference

You don't need to know the data type in advance, you let the runtime solve it on the fly, like this:

private static void updateValues(SqlDataReader reader)  
{
    USR_AddressItem item = new USR_AddressItem();
    item.UserId = GetConverter(item.UserId)(reader[UserDAL.USR_Address.FieldNames.UserId]);
}

And my magic is here:

static Func<string, T>  GetConverter<T>(T example)      
{
    return (x) => Convert<T>(x); 
}


static T Convert<T>(string val)
{
        Type destiny = typeof(T);

        // See if we can cast           
        try
        {
            return (T)(object)val;
        }
        catch { }

        // See if we can parse
        try
        {
            return (T)destiny.InvokeMember("Parse", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public, null, null, new object[] { val });
        }
        catch { }

        // See if we can convert
        try
        {
            Type convertType = typeof(Convert);
            return (T)convertType.InvokeMember("To" + destiny.Name, System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public, null, null, new object[] { val });
        }
        catch { }

        // Give up
        return default(T);
    }

Upvotes: 4

Mike Perrenoud
Mike Perrenoud

Reputation: 67898

In the case of a Guid it's going to be much different because there is no real conversion. See, building a Guid with a string must be done like this:

var guid = new Guid("DAABED91-39AC-4805-9015-1B03E4B5706A");

You could of course use Reflection for this, but it would be a pretty complex algorithm to determine what constructor to use for a type that doesn't have a real conversion.

However, for a number of other types you could consider something like this:

// would generate something like ToInt32...
var methodName = string.Format("To{0}", t.Name.Split('.').Last());

var methodInfo = Convert.GetType().GetMethod(methodName);
if (methodInfo == null) { return default(t); }

var val = methodInfo.Invoke(null, new object[] { valToConvert });

NOTE: this code is untested. It's meant as a guide, and I think it's pretty close, but you may have to massage it a little.

Upvotes: 1

Tim
Tim

Reputation: 15227

In the example you show, it would be simpler to just say:

Userid = new System.Guid(value);

since the constructor of a Guid takes a string to create the object.

That is, unless you're trying to do something else, in which case please clarify your question!

Upvotes: 4

Related Questions