Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否有一个.net序列化程序可以输出c#代码?_C#_.net_Serialization - Fatal编程技术网

是否有一个.net序列化程序可以输出c#代码?

是否有一个.net序列化程序可以输出c#代码?,c#,.net,serialization,C#,.net,Serialization,我正在寻找一个序列化程序,它可以获取一个实例,并将其序列化为一个字符串,该字符串将包含表示图形内容的c#代码。 该类的功能类似于JSON.NET中的SerializeObject 我知道只有一组非常狭窄的结构可以工作,但我感兴趣的结构非常简单,它们会工作 如果有人知道具有类似功能的Visual Studio可视化工具,则可获得额外积分 编辑: 在编译时,输出将在不同的应用程序中使用。我不需要在运行时对输出(c代码)进行反序列化,它会保存到一个文件中进行分析 var foo = new Foo()

我正在寻找一个序列化程序,它可以获取一个实例,并将其序列化为一个字符串,该字符串将包含表示图形内容的c#代码。 该类的功能类似于JSON.NET中的
SerializeObject

我知道只有一组非常狭窄的结构可以工作,但我感兴趣的结构非常简单,它们会工作

如果有人知道具有类似功能的Visual Studio可视化工具,则可获得额外积分

编辑: 在编译时,输出将在不同的应用程序中使用。我不需要在运行时对输出(c代码)进行反序列化,它会保存到一个文件中进行分析

var foo = new Foo() { Number = 1, Bar = new Bar() { Str = "Bar"}};
string sourceCode = Magic.SerializeObject(foo);
输出:

Foo obj = new Foo();
obj.Number = 1;
obj.RefType = null; // infer this
obj.Bar = new Bar();
obj.Bar.Str = "Bar";
是的,也不是

最接近的解决方案称为,它是大多数VisualStudio设计师和向导用来生成代码的方法


在仔细阅读您的评论后,我认为您应该彻底阅读MSDN中的部分,它将满足您的所有要求

您所寻找的是序列化,您不想每次都重新编译第二个项目,对吗?
您只需要验证,并且向前/向后兼容性

使用CodeDom编写类似的内容实际上相对简单:

class CSharpSerializer
{
    private readonly Dictionary<string, int> m_locals =
        new Dictionary<string, int>();

    private readonly List<CodeStatement> m_statements =
        new List<CodeStatement>();

    private string GetVariableName(string suggestedName)
    {
        suggestedName = suggestedName.TrimEnd("0123456789".ToCharArray());

        int n;
        if (m_locals.TryGetValue(suggestedName, out n))
        {
            n++;
            m_locals[suggestedName] = n;
            return suggestedName + n;
        }

        m_locals[suggestedName] = 1;
        return suggestedName;
    }

    public string SerializeObject(object obj)
    {
        m_statements.Clear();

        // dynamic used to make the code simpler
        GetExpression((dynamic)obj);

        var compiler = new CSharpCodeProvider();
        var writer = new StringWriter();
        foreach (var statement in m_statements)
        {
            compiler.GenerateCodeFromStatement(
                statement, writer, new CodeGeneratorOptions());
        }
        return writer.ToString();
    }

    private static CodeExpression GetExpression(int i)
    {
        return new CodePrimitiveExpression(i);
    }

    private static CodeExpression GetExpression(string s)
    {
        return new CodePrimitiveExpression(s);
    }

    private static CodeExpression GetExpression(DateTime dateTime)
    {
        // TODO: handle culture and milliseconds
        return new CodeMethodInvokeExpression(
            new CodeTypeReferenceExpression(typeof(Convert)), "ToDateTime",
            new CodePrimitiveExpression(Convert.ToString(dateTime)));
    }

    // and so on for other primitive types
    // and types that require special handling (including arrays)

    private CodeExpression GetExpression(object obj)
    {
        if (obj == null)
            return new CodePrimitiveExpression(null);

        var type = obj.GetType();
        string typeName = type.Name;

        string variable = GetVariableName(
            typeName[0].ToString().ToLower() + typeName.Substring(1));

        m_statements.Add(
            new CodeVariableDeclarationStatement(
                typeName, variable, new CodeObjectCreateExpression(typeName)));

        foreach (var property in type.GetProperties(
            BindingFlags.Public | BindingFlags.Instance))
        {
            var expression = GetExpression((dynamic)property.GetValue(obj));
            m_statements.Add(
                new CodeAssignStatement(
                    new CodePropertyReferenceExpression(
                        new CodeVariableReferenceExpression(variable),
                        property.Name),
                    expression));
        }

        return new CodeVariableReferenceExpression(variable);
    }
}
类CSharpSerializer
{
私有只读字典m_locals=
新字典();
私有只读列表m_语句=
新列表();
私有字符串GetVariableName(字符串建议名称)
{
suggestedName=suggestedName.TrimEnd(“0123456789.tocharray());
int n;
if(m_locals.TryGetValue(suggestedName,out n))
{
n++;
m_locals[建议名称]=n;
返回suggestedName+n;
}
m_locals[建议名称]=1;
返回建议的名称;
}
公共字符串序列化对象(对象obj)
{
m_语句。清除();
//dynamic用于简化代码
GetExpression((动态)obj);
var compiler=new CSharpCodeProvider();
var writer=新的StringWriter();
foreach(m_语句中的var语句)
{
compiler.GenerateCodeFromStatement(
语句、编写器、新代码生成器选项();
}
返回writer.ToString();
}
私有静态代码表达式GetExpression(int i)
{
返回新的CodePrimitiveExpression(i);
}
私有静态代码表达式GetExpression(字符串s)
{
返回新的CodePrimitiveExpression;
}
私有静态代码表达式GetExpression(DateTime DateTime)
{
//TODO:处理区域性和毫秒数
返回新的CodeMethodInvokeeExpression(
新的CodeTypeReferenceExpression(typeof(Convert)),“ToDateTime”,
新的CodePrimitiveExpression(Convert.ToString(dateTime));
}
//对于其他基本类型,依此类推
//以及需要特殊处理的类型(包括阵列)
私有代码表达式GetExpression(对象obj)
{
if(obj==null)
返回新的CodePrimitiveExpression(null);
var type=obj.GetType();
字符串typeName=type.Name;
字符串变量=GetVariableName(
typeName[0].ToString().ToLower()+typeName.Substring(1));
m_.Add(
新的CodeVariableDeclarationStatement(
typeName,变量,新的CodeObjectCreateExpression(typeName));
foreach(type.GetProperties中的var属性(
BindingFlags.Public | BindingFlags.Instance)
{
var expression=GetExpression((动态)property.GetValue(obj));
m_.Add(
新代码分配语句(
新的CodePropertyReferenceExpression(
新的CodeVariableReferenceExpression(变量),
物业名称),
表情),;
}
返回新的CodeVariableReferenceExpression(变量);
}
}

在很多情况下,此代码都会失败,但对于行为良好的类型(公共默认构造函数、所有公共实例属性都有setter、字段或非公共属性中没有隐藏重要状态、没有循环引用、没有命名空间冲突等),它会起作用。

您尝试过XmlSerializer吗?@Android我经常使用它。它只序列化为XML,而不是c#。我不知道一个现成的解决方案,但您可能想看看Visual Studio用于代码生成的T4文本模板。。。稍微反思一下,你就可以开始了……从技术上讲,这是C#code
Foo obj=JsonConvert.Deserialize(“[json]”)但它显然与示例输出不匹配。你介意分享一下你为什么需要C代码吗?伙计们,等等,你们误解了我在找什么。我不想在运行时发出代码/创建新类型,或者诸如此类的东西。我想获取一个数据结构,将其序列化为c代码表示。然后我将这个输出保存到一个文件中。我在稍后阶段获取这个输出,并将其用于另一个项目中(通常编译),以提供“真实”的测试数据。我希望它是c#,而不是JSON/XML/etc,因为如果/当我们更改类时,编译器可以确保数据结构匹配。很抱歉给您带来任何困惑。@jasper,基本上没有,为什么要序列化到源代码,本质上是反编译。以“圆形可折叠”的方式进行比较困难,尤其是在一般情况下。最终,您会得到一个更详细的状态表示。你可能会说它更容易让人阅读,但是XML和JSON在这方面非常好+1@Jodrell我想你应该把这个问题提出来;-)+1位的指向是准确的。我是指注释,但OK:-)事实上,我确实希望每次都重新编译,因为我们需要编译时检查,但看起来你对CodeDOM很在行,特别是svick提供的解决方案。谢谢你的帮助。非常感谢