Utilities.CoerceValue enhancement suggestion

Utilities.CoerceValue enhancement suggestion

Old forum URL: forums.lhotka.net/forums/t/7904.aspx


Regent posted on Thursday, October 29, 2009

Currently the very last technique Utilities.CoerceValue used in order to convert value is using type converter of the desiredType:


TypeConverter cnv = TypeDescriptor.GetConverter(desiredType);
if (cnv != null && cnv.CanConvertFrom(valueType))
return cnv.ConvertFrom(value);
else
{
cnv = TypeDescriptor.GetConverter(valueType);
if (cnv != null && cnv.CanConvertTo(desiredType))
return cnv.ConvertTo(value, desiredType);
eles throw;
}


In the database design I need to support several enum types are being converter into the same persistence type (desiredType). Each enum type have type converter assigned but persistence type have none converters assigned (and its quite maintainability issue to maintain symmetric conversion logic in both enum and database type converters).

What I suggest is to try valueType too before throwing an exception:

Currently the very last technique Utilities.CoerceValue used in order to convert value is using type converter of the desiredType:


TypeConverter cnv = TypeDescriptor.GetConverter(desiredType);
if (cnv != null && cnv.CanConvertFrom(valueType)) return cnv.ConvertFrom(value);
else{
cnv = TypeDescriptor.GetConverter(valueType);

}

RockfordLhotka replied on Thursday, October 29, 2009

I see what you are saying, and this probably makes sense. In fact, you might argue that the valueType converter should be tried first.

I'll add this to the wish list.

Regent replied on Friday, October 30, 2009

Thanks

As for me I can't decide which assumption to try is more ideologically right:

- source-class' converter should know how to convert to other classes (what is as analogy to 'obj.ToString()' for me);

or

- class-recipient's converter should be aware how to instantiate from other classes (more reminds me of 'Color.FromArgb(32)' and 'new DateTime(100032)');

As for me latter looks better because recipient-class should be more concerned about possible construction options rather that source-class... Indeed corresponds to the current code.

RockfordLhotka replied on Friday, October 30, 2009

I agree, it is not immediately clear which is better.

But since the point of CoerceValue() is to try every technique available for
type conversion, trying both seems smart.

Regent replied on Tuesday, November 10, 2009

Eventually I found that trying to to use Convert.ChangeType is incredibly expensive in case of exception.

Maybe my task is too specific, but I modified CoerceValue to have an additional logic regarding ChangeType:

1. If !(value is IConvertible) then it will try TypeConverters first.
2. If (value is IConvertible) then it will try ChangeType first but if it will fail it will try TypeConverters first next time.

Please review included .diff file.

Copyright (c) Marimer LLC