时间:2018-4-5来源:本站原创作者:佚名

去年2月份,随着VisualStudioUpdate5.5的发布,VisualC#迎来了它的最新版本:7.2.在这个版本中,有个让人难以理解的新特性,就是privateprotected访问修饰符(AccessModifier)。至此,C#语言的访问修饰符有以下几种:

private

protected

public

internal

internalprotected

privateprotected

既然有了private和protected,那么privateprotected又是什么?它跟internalprotected又有什么关系?本文简单介绍一下。

privateprotected是怎么回事

在解释privateprotected之前,首先让我们回顾一下internalprotected访问修饰符。internalprotected表示,相同程序集(Assembly)中的其它类型,或者当前类的子类,具有访问该类中internalprotected成员的能力,可以用下图表示:

在上图中:

程序集A中的X类,可以访问A类中的Method方法

程序集A中的B类,可以重载A类中的Method方法,B类中的其它成员也可以访问A类中的Method

程序集B中的C类,可以重载A类中的Method方法,C类中的其它成员也可以通过base.Method()访问A类中的Method

程序集B中C类的Method方法重载了A类的Method方法,因此,internal关键字被去掉,于是,程序集B中的Y类,无法访问C类中的Method方法

因此,internalprotected表示internal或者protected。

然而,privateprotected表示,仅有相同程序集(Assembly)中继承于当前类型的类,才能访问该类中privateprotected成员。换句话说,privateprotected就是访问者必须在相同程序集中(internal),同时还必须是被访问类型的子类(protected),可以用下图表示:

因此,privateprotected表示internal并且protected。

privateprotected何时使用

理论上讲,privateprotected完善了C#语言的封装性,提供了另一层级别的成员访问保护,听起来感觉让人费解又没什么用。那么,什么时候使用这个访问修饰符呢?现假设你正在设计一个框架,其中有个类,它提供对象存储功能,它的职责是保存给定的对象,而它的每一种实现都需要依赖于一个对象的序列化机制,比如:

publicsealedclassSerializationHelper{publicstringSerialze(objects){using(varmemoryStream=newMemoryStream()){varserializer=newXmlSerializer(s.GetType());serializer.Serialize(memoryStream,s);returnEncoding.UTF8.GetString(memoryStream.ToArray());}}}publicabstractclassDataStorage{privatereadonlySerializationHelperserializer=newSerializationHelper();protectedSerializationHelperSerializer=serializer;protectedabstractvoidSaveObject(objectobj);}publicsealedclassInMemoryDataStorage:DataStorage{privatereadonlyListstringserializedData=newListstring();protectedoverridevoidSaveObject(objectobj)=serializedData.Add(Serializer.Serialze(obj));}

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

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

internalsealedclassSerializationHelper{publicstringSerialze(objects){using(varmemoryStream=newMemoryStream()){varserializer=newXmlSerializer(s.GetType());serializer.Serialize(memoryStream,s);returnEncoding.UTF8.GetString(memoryStream.ToArray());}}}

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

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

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

internalsealedclassSerializationHelper{publicstringSerialze(objects){using(varmemoryStream=newMemoryStream()){varserializer=newXmlSerializer(s.GetType());serializer.Serialize(memoryStream,s);returnEncoding.UTF8.GetString(memoryStream.ToArray());}}}publicabstractclassDataStorage{privatereadonlySerializationHelperserializer=newSerializationHelper();privateprotectedSerializationHelperSerializer=serializer;protectedabstractvoidSaveObject(objectobj);}publicsealedclassInMemoryDataStorage:DataStorage{privatereadonlyListstringserializedData=newListstring();protectedoverridevoidSaveObject(objectobj)=serializedData.Add(Serializer.Serialze(obj));}

不过,一旦使用了privateprotected访问修饰符,DataStorage.Serializer属性就只能在DataStorage所在的程序集的子类中访问了。

privateprotected如何使用

privateprotected访问修饰符是C#7.2的新特性。自从使用Roslyn编译器服务的C#6.0开始,C#编译器的版本更新就可以与.NETFramework和VisualStudio的发布分离开来了。这一点在C#7.x(包括7.和7.2)的发布中逐步显现出来。在VisualStudio的编译高级选项中,开发人员可以很方便地选择所需的C#版本:

如上图所述,在C#项目上点右键,在项目属性的Build标签页中,点击Advanced按钮,在AdvancedBuildSettings对话框中,通过Languageversion下拉框来选择所需的C#语言版本。其中:

C#latestmajorversion(default):C#最新的主版本,也就是与VisualStudio一起发布的主要版本,在VS上对应C#7.0

C#latestminorversion(latest):C#的最新版,通常通过VS的升级包获得

要使用privateprotected访问修饰符,则需要在此选择C#latestminorversion(latest),或者C#7.2.

总结

本文对C#7.2的新特性:privateprotected访问修饰符进行了解析,并通过案例来说明它的应用场景以及VisualStudio对于C#新特性的支持。

赞赏

长按







































西安白癜风医院
治白癜风有什么土方

转载请注明原文网址:http://www.helimiaopu.com/bbqb/6164.html

------分隔线----------------------------