为什么C#DataMember属性允许私有字段和属性的序列化?

时间:2018-03-07 09:09:45

标签: c# oop

如果您将DataMember属性添加到任何字段或属性(包括私有字段),它们仍会被序列化。 Microsoft明确地注意到这一点in their docs

"您可以将DataMemberAttribute应用于私有字段或属性。请注意,该成员返回的数据(即使它是私有的)将被序列化和反序列化,因此可被恶意用户或进程查看或拦截。"

例如:

public class MyClass
{
    [DataMember(Name = "pushed_at")] 
    private string JsonDate { get; set; } //PRIVATE!

    [IgnoreDataMember]
    public DateTime PushedAt
    {
        get { return JsonDate; }
    }
}

var serializer = new DataContractJsonSerializer(typeof(List<MyClass>));
var streamTask = client.GetStreamAsync("https://api.mysite.com/hit");
var classes = serializer.ReadObject(await streamTask) as List<MyClass>;

foreach (var myClass in classes)
{
    Console.WriteLine(myClass.JsonDate); //Error because private
    Console.WriteLine(myClass.PushedAt); //Ok and shows serialized data
}

为什么这有意义?自封装原理不是比序列化更基础吗? DataMember属性是否真的可以访问课堂外的私人财产,还是我遗漏了一些东西?

如果您将JsonDate公开并将其设为private制定者,则会发生同样的事情。

2 个答案:

答案 0 :(得分:5)

  

自封装的原则不是比基本原理更为根本   序列

序列化使用反射进行,因此我们可以更改您的问题:

  

自封装的原则不是比基本原理更为根本   反射?

所以here就是答案

答案 1 :(得分:2)

  

自封装的原理是否比序列化更为基础?

没有。 &#34;纯&#34;编程原则原则上很好,但有时你只需要完成任务。

如果包括反序列化为私有成员,无论出于何种原因,.NET设计团队显然决定他们不会阻止您这样做,即使这意味着代码更清晰在那里。

他们故意做出这个选择,正如你声称的那样documented