Skip to content

Instantly share code, notes, and snippets.

@paxbun
Created August 9, 2021 08:41
Show Gist options
  • Save paxbun/a7f87ba6899509cfa05f30136921b6bb to your computer and use it in GitHub Desktop.
Save paxbun/a7f87ba6899509cfa05f30136921b6bb to your computer and use it in GitHub Desktop.
C# arbitrary type to dictionary
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
public class Foo
{
public string BarBar { get; set; }
public int BazBazBaz { get; set; }
}
public class Program
{
public static void Main()
{
var foo = new Foo
{
BarBar = "Hello",
BazBazBaz = 12345
}.Convert();
foreach (var (key, value) in foo)
{
Console.WriteLine("{0} {1}", key, value);
}
}
}
public static class FormDataConverterExtensions
{
public static Dictionary<string, string> Convert<T>(this T arg)
{
return FormDataConverter<T>.Convert(arg);
}
}
public static class FormDataConverter<T>
{
public static Func<T, Dictionary<string, string>> Convert { get; private set; }
static FormDataConverter()
{
var sourceType = typeof(T);
var sourceParam = Expression.Parameter(sourceType);
var sourceTypeProperties = sourceType.GetProperties();
List<ElementInit> elementInits = new(sourceTypeProperties.Length);
var dictionaryType = typeof(Dictionary<string, string>);
var dictionaryNew = Expression.New(dictionaryType);
var addMethod = dictionaryType.GetMethod("Add");
var stringType = typeof(string);
foreach (var sourceProperty in sourceTypeProperties)
{
var sourceGetMethod = sourceProperty.GetGetMethod();
if (sourceGetMethod is null)
continue;
var key = Expression.Constant(sourceProperty.Name);
var value = Expression.Call(sourceParam, sourceGetMethod);
var valueType = value.Type;
if (!valueType.Equals(stringType))
{
var valueToString = value.Type.GetMethod("ToString", Array.Empty<Type>());
value = Expression.Call(value, valueToString);
}
elementInits.Add(Expression.ElementInit(addMethod, key, value));
}
Convert = Expression.Lambda<Func<T, Dictionary<string, string>>>(
Expression.ListInit(dictionaryNew, elementInits),
sourceParam
).Compile();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment