Get property Type and convert String to corresponding Type

Viewed 5608

I am using CSOM to update some Task of a Project Server Project.

Which property has to be updated is not defined the code finds out dynamically what to update based on the property name as String.

For better understanding I wore a simplified version of my code

//fieldName = "ActualWorkTimeSpan"; value = "16:00:00";
private void Start(string fieldName, string value)
{
    DraftTask draftTask = GetDraftTask();

    Update(draftTask, fieldName, value);

    PublishAndCheckin(draftTask);
}

private static void Update(DraftTask draftTask, string fieldName, string value)
{
    // skip updating if field is Equal
    if (GetPropValue(draftTask, fieldName).ToString() == value)
        return;

    // update of the task
    SetPropValue(draftTask, fieldName, value);

}

private static object GetPropValue(object src, string propName)
{
    return src.GetType().GetProperty(propName).GetValue(src, null);
}

private static void SetPropValue(DraftTask src, string propName, object value)
{
    src.GetType().GetProperty(propName).SetValue(src, value);
}

I can use GetPropValue() without problem but for SetPropValue() I would need the value to be in the right type.

In this case it would be "System.TimeSpan" for the property "ActualWorkTimeSpan". So I would need to convert the string "15:00:00" to TimeSpan.

It would be easy to do if it were TimeSpan every time, but I could be that the Field "Cost" is set to be updated.

Update(draftTask, "Cost", "500");

So my question is if it is Possible to find out what type the field has and than convert my value to the same type.

3 Answers

I use TypeDescriptor.GetConverter that takes a Type and returns a TypeConverter that knows how to convert a string to the specified Type.

You can then call TypeConverter.ConvertFromString to convert the string to the required Type.

Your code would look like:

var propType = src.GetType().GetProperty(propName).PropertyType;
var converter = TypeDescriptor.GetConverter(propType);
var convertedObject = converter.ConvertFromString(src);

You can do this, by using Convert.ChangeType method.

private static void SetPropValue(DraftTask src, string propName, object value)
{
    var property = src.GetType().GetProperty(propName);
    var valueToSet = Convert.ChangeType(value, property.PropertyType);
    property.SetValue(src, valueToSet);
}

ref, is useless in this case. It is used when you assign the parameter in the called method and have it also be assigned at the calling site (the scope of the calling method).

The simplest option is to change the method signature to be generic or take an object type and actually pass in the correct data type in the first place. For example:

private static void Update(DraftTask draftTask, string fieldName, object value)
{
    //snip
}

Or generic:

private static void Update<T>(DraftTask draftTask, string fieldName, T value)
{
    //snip
}

And now you call it with the correct type, for example:

var timeSpan = new TimeSpan(...);
Update(ref draftTask, "ActualWorkTimeSpan", timeSpan);
Related