VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • C#教程之解析Visual C# 7.2中的private protected访问修饰(2)

上面的代码中,SerializationHelper提供了一种将对象序列化成XML字符串的机制;DataStorage是所有对象数据存储的基类,它当然也为其子类提供了一个访问对象序列化器的方式。由于这个对象序列化器是提供给其子类调用的,因此,DataStorage中的Serializer属性是protected的。最后,InMemoryDataStorage继承了DataStorage,通过调用由基类提供的Serializer属性,实现了SaveObject方法。

整个实现当然没有问题。可是,通过审核所有类型的可见性,我们发现,我们不打算将SerializationHelper这个类暴露给外界,也就是不希望其它的程序集能够直接访问SerializationHelper类,于是,我们将它设置成internal的。也就是:

1
2
3
4
5
6
7
8
9
10
11
12
internal sealed class SerializationHelper
{
    public string Serialze(object s)
    {
        using (var memoryStream = new MemoryStream())
        {
            var serializer = new XmlSerializer(s.GetType());
            serializer.Serialize(memoryStream, s);
            return Encoding.UTF8.GetString(memoryStream.ToArray());
        }
    }
}

好了,问题来了,编译器开始抱怨了,说SerializationHelper类的访问级别比DataStorage.Serializer属性的访问级别要低:

image

道理显而易见:DataStorage.Serializer属性在DataStorage的子类中即可访问,这个子类可以是在DataStorage所在的程序集中,也可以是在另一个程序集中。然而,这个属性的依赖类型:SerializationHelper类,却只能在DataStorage所在的程序集中才能被访问。

于是,能量巨大的private protected闪亮登场。将DataStorage.Serializer属性的访问修饰符从protected改为private protected,问题就解决了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
internal sealed class SerializationHelper
{
    public string Serialze(object s)
    {
        using (var memoryStream = new MemoryStream())
        {
            var serializer = new XmlSerializer(s.GetType());
            serializer.Serialize(memoryStream, s);
            return Encoding.UTF8.GetString(memoryStream.ToArray());
        }
    }
}
 
public abstract class DataStorage
{
    private readonly SerializationHelper serializer = new SerializationHelper();
    private protected SerializationHelper Serializer => serializer;
    protected abstract void SaveObject(object obj);
}
 
public sealed class InMemoryDataStorage : DataStorage
{
    private readonly List<string> serializedData = new List<string>();
    protected override void SaveObject(object obj)
        => serializedData.Add(Serializer.Serialze(obj));
}

相关教程