4

我正在用 C# 开发一个应用程序,该应用程序在表单上声明了一个接口:

public partial class frmProjectForm : Form, IProjectInfo
{

}

public interface IProjectInfo
{
    string ProjectName { get; set; }
    string ProjectTitle { get; set; }
    string ProjectDescription { get; set; }
    string ProjectAuthor { get; set; }
    string ProjectCopyright { get; set; }
    string ProjectTrademark { get; set; }
    string ProjectCreationDate { get; set; }
    string ProjectVersion { get; set; }
    string ProjectFileName { get; }
    string ProjectFilePath { get; }
    string FullProjectPath { get; }
}

在应用程序的某个地方我想这样做:

frmProjectForm f = new frmProjectForm();
f.ShowDialog(this);
...
...
IProjectInfo getProjectInfoMembersOnly = (IProjectInfo)f;

// persist the IProjectInfo members to JSON
string project = JsonConvert.SerializeObject( getProjectInfoMembersOnly );

JsonConvert.SerializeObject方法正在爆炸并抱怨 Button 控件上的一些自引用循环。转换操作不排除表单,我不知道为什么,因为我只想让接口转换只返回接口成员。

我究竟做错了什么?

4

2 回答 2

1

在我看来,序列化代码适用于对象的实际类型,而不是作为参数传递的类型(函数甚至可能接受 type 的参数object,而不是泛型函数SerializeObject<T>(T obj))。

如果您希望对对象进行切片,恐怕您必须自己执行切片,方法是创建一个实现接口的对象并仅复制其成员。

public class ProjectInfo : IProjectInfo
{
    public string ProjectName { get; set; }
    public string ProjectTitle { get; set; }
    public string ProjectDescription { get; set; }
    public string ProjectAuthor { get; set; }
    public string ProjectCopyright { get; set; }
    public string ProjectTrademark { get; set; }
    public string ProjectCreationDate { get; set; }
    public string ProjectVersion { get; set; }
    public string ProjectFileName { get; private set; }
    public string ProjectFilePath { get; private set; }
    public string FullProjectPath { get; private set; }

    public ProjectInfo(IProjectInfo src)
    {
        this.ProjectName = src.ProjectName;
        this.ProjectTitle = src.ProjectTitle;
        this.ProjectDescription = src.ProjectDescription;
        this.ProjectAuthor = src.ProjectAuthor;
        this.ProjectCopyright = src.ProjectCopyright;
        this.ProjectTrademark = src.ProjectTrademark;
        this.ProjectCreationDate = src.ProjectCreationDate;
        this.ProjectVersion = src.ProjectVersion;
        this.ProjectFileName = src.ProjectFileName;
        this.ProjectFilePath = src.ProjectFilePath;
        this.FullProjectPath = src.FullProjectPath;
    }
}

然后你可以这样使用它:

frmProjectForm f = new frmProjectForm();
f.ShowDialog(this);
...
...
IProjectInfo getProjectInfoMembersOnly = new ProjectInfo(f); //I only changed this line

// persist the IProjectInfo members to JSON
string project = JsonConvert.SerializeObject( getProjectInfoMembersOnly );
于 2013-08-27T12:23:33.397 回答
1

如果您仅使用接口进行序列化(您的问题不清楚),则根本不需要接口。JSON.NET 提供了属性来标记哪些字段应该被序列化。即使您将接口用于其他用途,也没有理由不能像这样定义您的类:

// Use optin so you don't have to worry about fields generated by the designer.
[JsonObject(MemberSerialization.OptIn)]
public partial class frmProjectForm : Form
{
    [JsonProperty]
    public string ProjectName { get; set; }
    [JsonProperty]
    public string ProjectTitle { get; set; }
    [JsonProperty]
    public string ProjectDescription { get; set; }
    [JsonProperty]
    public string ProjectAuthor { get; set; }
    [JsonProperty]
    public string ProjectCopyright { get; set; }
    [JsonProperty]
    public string ProjectTrademark { get; set; }
    [JsonProperty]
    public string ProjectCreationDate { get; set; }
    [JsonProperty]
    public string ProjectVersion { get; set; }
    [JsonProperty]
    public string ProjectFileName { get; }
    [JsonProperty]
    public string ProjectFilePath { get; }
    [JsonProperty]
    public string FullProjectPath { get; }

    // . . . Other properties, buttons, and form fields
}

然后,当您调用 时JSONConvert.SerializeObject(),只有标记为的字段JsonProperty才会被序列化。

于 2013-08-27T12:32:35.933 回答