Created
August 9, 2021 08:41
-
-
Save paxbun/a7f87ba6899509cfa05f30136921b6bb to your computer and use it in GitHub Desktop.
C# arbitrary type to dictionary
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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