using System.CodeDom.Compiler;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Collections.Generic;
public static void Main()
var value = new KeyValuePair<int, string>[] { new KeyValuePair<int, string>(-21, "ab") };
var expression = CodeDomUtility.Serialize(value);
var unit = TestField(expression, value.GetType());
DumpCode(unit, new Microsoft.CSharp.CSharpCodeProvider());
DumpCode(unit, new Microsoft.VisualBasic.VBCodeProvider());
static CodeCompileUnit TestField(CodeExpression expression, Type fieldType)
var unit = new CodeCompileUnit();
var ns = new CodeNamespace("Sample");
ns.Imports.Add(new CodeNamespaceImport("System"));
ns.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
var class1 = new CodeTypeDeclaration("Foo");
var field = new CodeMemberField(fieldType, "Bar") { InitExpression = expression };
class1.Members.Add(field);
static void DumpCode(CodeCompileUnit unit, CodeDomProvider provider)
Console.WriteLine(provider.ToString());
var tw = new IndentedTextWriter(Console.Out, " ");
provider.GenerateCodeFromCompileUnit(unit, tw, new CodeGeneratorOptions());
static partial class CodeDomUtility
static CodeExpression _SerializeArray(Array arr)
if (1 == arr.Rank && 0 == arr.GetLowerBound(0))
var result = new CodeArrayCreateExpression( arr.GetType());
foreach (var elem in arr)
result.Initializers.Add(Serialize(elem));
throw new NotSupportedException("Only SZArrays can be serialized to code.");
public static CodeExpression Serialize(object val)
return new CodePrimitiveExpression(null);
return new CodePrimitiveExpression(val);
if (val is Array && 1 == ((Array)val).Rank && 0 == ((Array)val).GetLowerBound(0))
return _SerializeArray((Array)val);
var conv = TypeDescriptor.GetConverter(val);
if (conv.CanConvertTo(typeof(InstanceDescriptor)))
var desc = conv.ConvertTo(val, typeof(InstanceDescriptor)) as InstanceDescriptor;
throw new NotSupportedException(string.Format("The type \"{0}\" could not be serialized.", val.GetType().FullName));
var ctor = desc.MemberInfo as ConstructorInfo;
var result = new CodeObjectCreateExpression(ctor.DeclaringType);
foreach (var arg in desc.Arguments)
result.Parameters.Add(Serialize(arg));
throw new NotSupportedException(string.Format("The instance descriptor for type \"{0}\" is not supported.", val.GetType().FullName));
var valType = val.GetType();
if (valType.IsGenericType && valType.GetGenericTypeDefinition() == typeof(KeyValuePair<,>))
var kvpType = new CodeTypeReference(typeof(KeyValuePair<,>));
foreach (var arg in val.GetType().GetGenericArguments())
kvpType.TypeArguments.Add(arg);
var result = new CodeObjectCreateExpression(kvpType);
for(int ic= kvpType.TypeArguments.Count,i = 0;i<ic;++i)
var prop = val.GetType().GetProperty(0==i?"Key":"Value");
result.Parameters.Add(Serialize(prop.GetValue(val)));
throw new NotSupportedException(string.Format("The type \"{0}\" could not be serialized.", val.GetType().FullName));
throw new NotSupportedException(string.Format("The type \"{0}\" could not be serialized.", val.GetType().FullName));