Does Linqpad have support for truncating numeric fields to a maximum number of decimal places similar to the "Results" configuration settings that apply to DateTime output:
Assuming Linqpad doesn't have built in support (no option in the Results settings tab), are there any other options? I have an on object with over hundreds of double
properties and I'm trying to avoid writing Math.Round(obj.Property, 4, MidpointRound.ToZero)
200 times.
CodePudding user response:
With Linqpad 7 you can customise the dump command by adding this to your query.
static object ToDump(object o)
{
if (o is double d) return Math.Round(d, 4, MidpointRounding.ToZero);
return o;
}
Example
void Main()
{
Single s = 1.2345678f;
Double d = (double) s;
(new { s, d }).Dump();
}
By default this gives
but with the customised Dump it gives
//supports any collection inheriting from IEnumerable<T>
var myEnumerable = new List<MyObject>();
//set precision and MidpointRounding if desired
myEnumerable.NumericTruncate(4, MidpointRounding.ToZero).Dump();
//set precision with natural rounding
myEnumerable.NumericTruncate(4).Dump();
NumericFormat()
This method output string values formatted with consistent lenghth.
//supports any collection inheriting from IEnumerable<T>
var myEnumerable = new List<MyObject>();
//set precision and MidpointRounding if desired
myEnumerable.NumericFormat(4, MidpointRounding.ToZero).Dump();
//set precision with natural rounding
myEnumerable.NumericFormat(4).Dump();
MyExtensions Methods
Paste the code below into your MyExtentions file in Linqpad:
public static IEnumerable<ExpandoObject> NumericTruncate<T>(this IEnumerable<T> values,
int precision, MidpointRounding? round = null)
{
var itemType = typeof(T);
var valArr = values.ToArray();
var types = new HashSet<Type>() { typeof(decimal), typeof(double), typeof(float) };
var typesNullable = new HashSet<Type>() { typeof(decimal?), typeof(double?), typeof(float?) };
var props = itemType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
for (int i = 0; i < valArr.Length; i )
{
IDictionary<string, object> obj = new System.Dynamic.ExpandoObject();
foreach (var prop in props)
{
var val = prop.GetValue(valArr[i]);
if (types.Contains(prop.PropertyType))
{
obj[prop.Name] = round.HasValue
? Math.Round(Convert.ToDouble(val), precision, round.Value)
: Math.Round(Convert.ToDouble(val), precision);
}
else if (typesNullable.Contains(prop.PropertyType))
{
var valNull = (double?)val;
if (valNull.HasValue)
obj[prop.Name] = round.HasValue
? Math.Round(Convert.ToDouble(valNull.Value), precision, round.Value)
: Math.Round(Convert.ToDouble(valNull.Value), precision);
else
obj[prop.Name] = null;
}
else
obj[prop.Name] = val;
}
yield return (ExpandoObject) obj;
}
}
public static IEnumerable<ExpandoObject> NumericFormat<T>(this IEnumerable<T> values,
int precision = 4, MidpointRounding? round = null)
{
var itemType = typeof(T);
var valArr = values.ToArray();
var types = new HashSet<Type>() { typeof(decimal), typeof(double), typeof(float) };
var typesNullable = new HashSet<Type>() { typeof(decimal?), typeof(double?), typeof(float?) };
var pattern = "#,##0." string.Concat(Enumerable.Range(1, precision).Select(h=> "0"));
var props = itemType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
for (int i = 0; i < valArr.Length; i )
{
IDictionary<string, object> obj = new System.Dynamic.ExpandoObject();
foreach (var prop in props)
{
var val = prop.GetValue(valArr[i]);
if (types.Contains(prop.PropertyType))
{
obj[prop.Name] = round.HasValue
? Math.Round(Convert.ToDouble(val), precision, round.Value).ToString(pattern)
: Math.Round(Convert.ToDouble(val), precision).ToString(pattern);
}
else if (typesNullable.Contains(prop.PropertyType))
{
var valNull = (double?)val;
if (valNull.HasValue)
obj[prop.Name] = round.HasValue
? Math.Round(Convert.ToDouble(valNull.Value), precision, round.Value).ToString(pattern)
: Math.Round(Convert.ToDouble(valNull.Value), precision).ToString(pattern);
else
obj[prop.Name] = null;
}
else
obj[prop.Name] = val;
}
yield return (ExpandoObject)obj;
}
}