2010-11-15 104 views
17

这不能在C#中完成。任何方式来做到这一点?将“NonSerializedAttribute”设置为自动属性

...

,万一我的小双关语不明白,我的意思是:我怎么可以标记在C#中的财产作为非序列化?当然,当属性包含逻辑时,很自然无法做到这一点,但自动属性是可序列化的,因此,我希望有一些方法可以让我阻止它们的序列化。

+3

这是不可能的。 – SLaks 2011-01-02 00:20:34

回答

5

编辑*: 自动实现的属性是由一个匿名的土地,你真的没有获得支持,属性的目的是通过反射机制基础来控制。这些字段不能被反射机制引用(因为它们是匿名的)。此编译器功能需要对自动属性生成进行大量更改......它还需要编译器将自动属性作为字段来处理,以便将字段属性标记到其上。

要回答这个问题的更基本的部分 - 你的观点是自动属性是序列化的,所以应该有一种方法来控制它们的序列化。你是对的 - 但汽车属性是一种速记,从来没有设计为给你充分的灵活性,而是让你可以在需要的时候轻松扩展功能。

  • 我在答案的正文中添加了更多来自我的评论的答案。
+0

我不是C#noob :: - )。我知道这些事情。即便如此,编译器可以添加一个特殊的自动属性检查并允许NonSerialized属性。如果他们被序列化,他们应该被标记为忽​​略。我知道我可以做到这一点,如果我创建setter/getters,但这是另一个故事,并且与我的问题无关:: - )。 – Axonn 2011-04-06 00:02:00

+1

:) 在这种情况下,我为您提供了一个更好的解释: 自动实现的属性由匿名字段支持,您无法真正访问它,属性被设计为由基于反射的机制控制。这些字段不能被反射机制引用(因为它们是匿名的)。 您的编译器功能需要对自动属性生成进行大量更改... 它还需要编译器将auto-properties作为字段来处理,以便将字段属性标记到字段属性上。 – NightDweller 2011-04-06 21:06:40

+0

我注意到,这仍然不能回答你的问题的根本部分 - 你的观点是自动属性是序列化的,所以应该有一种方法来控制它们的序列化。 你是对的 - 但汽车性能是一种速记,从来没有被设计为给你充分的灵活性,而是让你可以在需要的时候轻松地延长其功能。 – NightDweller 2011-04-06 21:16:53

-4

[NonSerialized] public decimal yourproperty;

(十进制为例。)

还要记住,如果你想使你的类自动初始化非序列化成员,使用IDeserializationCallback接口,然后实现IDeserializationCallback.OnDeserialization。

+5

他说**财产**。这是一个领域。 – SLaks 2010-11-15 13:24:53

+0

o,是的。我错过了。 – 2010-11-15 13:29:54

1

我的理论是的,这是可能的。在实际中,不可能。

序列化类只适用于专用字段。当你定义一个自动属性时;在后台编译器会自动为它生成一个专用字段。这意味着这是一种语言功能,而不是.net框架功能。

还有序列化类包含在redbits中,这是任何更改被禁止的兼容性,除了错误修复。

我希望这有帮助。

7
[NonSerialized] 
    public string MyProperty { get; set; } 

是错误的

[XmlIgnore] 
    public string MyProperty { get; set; } 

是不是一个错误

非序列化指示可序列化类的某个字段不应被序列化。

XmlIgnore指示的XmlSerializer的Serialize方法不序列化公共字段或公共读/写属性值

所以,如果你问

我希望有一些让我阻止他们的序列化的方式。

的回答是,如果你使用的XmlSerializer

+0

将'XmlIgnoreAttribute'应用到属性导致该属性不再出现在生成的XML文档中。 – 2015-10-12 20:13:10

1

什么上面说的是对的:你不能阻止一个自动实现的属性通过设置如[非序列化]属性正在连载。它只是不起作用。

但是,如果您使用WCF [DataContract],那么工作是[IgnoreDataMember]属性是什么。因此,

[DataContract] 
public class MyClass 
{ 
    [DataMember] 
    public string ID { get; set; } 

    [IgnoreDataMember] 
    public string MySecret { get; set; } 
} 

将WCF序列化。

尽管由于WCF是一种选择加入技术,您也可以忽略[IgnoreDataMember]并且它也可以工作。因此,也许我的评论是一个小学院;-)

0

你可以用Mono.Cecil,一个字节码操作库做到这一点。理论上,您可以将自定义属性添加到隐藏的支持字段。然而,这很不方便,我认为这不是一个例子。

如果你有一个自己的后处理器的大型应用程序,你可以考虑创建自己的替代NonSerializedAttribute,可以应用于属性。然后后处理器可以使用Mono.Cecil或类似的方法将NonSerializedAttribute应用于后台字段。大型应用程序经常进行这样的后处理以节省多余的打字量是很常见的。

3

对于事件,您可以使用[field:NonSerialized],但对于自动属性,这不起作用。看起来这也是处理自动属性的一种非常合乎逻辑的方式,但由于某种原因,它似乎并未实现。