确定在运行时序列化哪些属性

tym*_*tam 8 c# serialization

让我们假设我必须在级别中序列化Car类的对象,例如Internal和Public.公共级别中的某些属性不应序列化,因为它们是内部的.

在这个时候,我能想到的最简单的方法就是使用继承:

class CarPublic {
  public int PropX {get;set}
}

class CarInternal: CarPublic {
  public string PropY {get;set}
}
Run Code Online (Sandbox Code Playgroud)

然后我可以

object ToSerialize() {
 CarInternal car = GetCar();
 if( level == Level.Public ) { 
    return car as CarPublic;
 } else {
     return car;
 }
}
Run Code Online (Sandbox Code Playgroud)

ToSerialize()的结果由框架(我无法控制)并序列化为JSON或XML.

为简单起见,我省略了XML序列化属性.

这感觉就像一个黑客和黑客只带你到目前为止.有没有更好的方法(方式?)来实现这一目标?

我认为现在很清楚,但我想避免为JSON和XML编写自己的序列化方法.

在此先感谢Tymek

==编辑

为了澄清,我希望能够序列化多个级别:

class Car0 {
  public int PropA {get;set}
}

class Car1: Car0 {
  public string PropB {get;set}
}

class Car2: Car1 {
  public int PropC {get;set}
}

class Car3: Car2 {
  public string PropD {get;set}
}
Run Code Online (Sandbox Code Playgroud)

object ToSerialize( Level level ) {
 Car3 car = GetCar();
 switch( level ) {
   case Level.Zero: return car as Car0;
   case Level.One: return car as Car1;
   case Level.Two: return car as Car3;
   case Level.Three: return car as Car4;
 }
 return null;
}
Run Code Online (Sandbox Code Playgroud)

==选择方法

我将Marc Gravell的答案标记为答案,因为它提供了C#及其"标准"组件如何支持我所要求的一般信息.

但是我认为我的问题的最佳方法是使用如上所示的代理类,并使用如下所示的方法在这个多级模式中序列化类.

public interface ICar {
    Car0 As0();
    Car1 As1();
    Car2 As2();
    Car3 As3();
 ...
 }
Run Code Online (Sandbox Code Playgroud)

这允许保持Car0..3类非常简单,只有属性,以维护和理解.

Mar*_*ell 5

这很大程度上取决于您使用的序列化框架.你提到xml和json - 首先要注意的是你可以装饰:

[XmlIgnore]
public int PropX {get;set;}
Run Code Online (Sandbox Code Playgroud)

要么

[ScriptIgnore]
public int PropX {get;set;}
Run Code Online (Sandbox Code Playgroud)

XmlSerializerJavascriptSerializer将响应.如果你需要在每个实例的基础上决定,还有就是ShouldSerialize**Specified模式:

public bool ShouldSerializePropX() {
   // return true to serialize, false to omit
}
Run Code Online (Sandbox Code Playgroud)

以上是基于名称的模式,由XmlSerializer其他人使用; 它有一个双胞胎:

[XmlIgnore, Browsable(false)]
public bool PropXSpecified {
    get { /* return true to serialize, false to omit */ }
    set { /* can just drop this value - don't need to assign */ }
}
Run Code Online (Sandbox Code Playgroud)

你不需要做任何事情来连接它们 - 它们会自动工作.

不同的序列化器允许不同的模式

此外,有时您可以[XmlIgnore]在运行时添加一些内容- 例如via XmlAttributeOverrides,或者任何给定序列化程序的等效项.