'Build an expression tree that can handle any type/class with a "TryParse()" method
i have the following method that returns a "value parser" delegate according to the input type. it works fine but i'd like to get rid of the switch statements and type checks and be able to return a value parser delegate for any type that has a TryParse() method.
internal static Func<object?, (bool isSuccess, object value)>? ValueParser(this Type type)
{
type = Nullable.GetUnderlyingType(type) ?? type;
if (type.IsEnum)
return input => (Enum.TryParse(type, ToString(input), out var res), res!);
switch (Type.GetTypeCode(type))
{
case TypeCode.String:
return input => (true, input!);
case TypeCode.Boolean:
return input => (bool.TryParse(ToString(input), out var res), res);
case TypeCode.DateTime:
return input => (DateTime.TryParse(ToString(input), out var res), res);
//other supported types go here...
case TypeCode.Object:
if (type == Types.Guid)
{
return input => (Guid.TryParse(ToString(input), out var res), res);
}
else if (type == Types.TimeSpan)
{
return input => (TimeSpan.TryParse(ToString(input), out var res), res!);
}
break;
}
return null; //unsupported types will cause a null return
static string? ToString(object? value)
{
if (value is string x)
return x;
return value?.ToString();
}
}
i believe the solution would be to build an expression tree something like below. but i haven't got the slightest clue how to go about building an expression tree correctly. so far all i have is the following:
internal static Func<object?, (bool isSuccess, object value)>? ValueParser(this Type type)
{
type = Nullable.GetUnderlyingType(type) ?? type;
var inputParam = Expression.Parameter(typeof(string), "input");
if (type == Types.String)
{
//no need for conversion if input type is string. so delegate should simply return a tuple (true,"inputValue").
var returnTarget = Expression.Label(type);
var returnCall = Expression.Return(returnTarget, inputParam);
}
var parsedVar = Expression.Variable(type, "parsed");
var tryParseCall = Expression.Call(
type,
"TryParse",
null,
inputParam,
parsedVar);
//need to compile the expression and return here.
//if the input type doesn't have a TryParse() method, null should be returned.
//also not sure if we need Expression.Convert() to handle value types.
}
i've been banging my head against the wall on this for a few days without much success. would really appreciate any help you can provide. thanks!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
