C# 转换到不排除表单成员的接口
我正在用C#开发一个应用程序,它在表单上声明了一个接口:C# 转换到不排除表单成员的接口,c#,json,interface,casting,C#,Json,Interface,Casting,我正在用C#开发一个应用程序,它在表单上声明了一个接口: public partial class frmProjectForm : Form, IProjectInfo { } public interface IProjectInfo { string ProjectName { get; set; } string ProjectTitle { get; set; } string ProjectDescription { get; set; } str
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控件上存在一些自引用循环。转换操作并不排除表单,我不知道为什么,因为我只希望接口转换只返回接口成员
我做错了什么?序列化代码处理对象的实际类型,而不是作为参数传递的类型,这在我看来很正常(函数甚至可能接受类型为
object
的参数,而不是泛型函数序列化对象(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 );
如果您只使用接口进行序列化(您的问题不清楚),那么您根本不需要接口。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
的字段才会被序列化。我不太确定,但我认为,在序列化时,仅将实例强制转换到接口不会隐藏实例属性……您仍在序列化该实例。如果您只需要接口属性,为什么要继承表单?@AMember我实际上并没有继承表单——它是一个继承接口的表单。我想创建一个标准化的表单,在这里我可以使用IProjectInfo
接口作为方法参数,而不是指定具体的表单实例。我认为这是一个很好的解决方案。我已经有了一个继承了IProjectInfo
的具体类,所以我将在你的切片建议中使用它。但是在看到@tandrewnichols的答案后,我认为它比我的要好得多。