黑马程序员_学习日记44_611基础加强(扩展方法、XML、深拷贝浅拷贝、特性)

22 篇文章 0 订阅

一、扩展方法:

//1、增加一个静态类

public static class StringExt

{

//2、在静态类中增加一个静态方法,带有this的参数表示当前的IsEmail方法是给string类型扩展的

public static bool IsEmail(this string str)

{

       // 扩展方法只是看起来像string中的方法,其实根本不是string类自己的成员,所以在扩展方法中不能访问类中原来的私有成员

       return Regex.IsMatch(str,@”^\w+@\w+\.\w+$”);

}

 

二、XML基础

(一)XMLHTML的区别:

1、  XML有且只有一个根元素

2、  XML中元素必须关闭

3、  XML中元素的属性值必须用引号。

4、  XML大小写敏感(CaseSensitive

(二)xml文件读写

//1、加载xml文件

XDocument xDoc = xDocument.Load(“x1.xml”);

//循环遍历每个节点

//2、获取根元素

XElement xeRoot = xDoc.Root;

订单案例:

订单号:doc.Root.Element(“OrderNumber”).Value

遍历订单项:

foreach(Xelement element in doc.Root.Descendants(“Items”).Descendants(“OrderItem”))

{

       Console.WriteLine(“商品名:{0},数量:{1}”,element.Element(“ItemName”).Value,element.Element(“Count”).Value);

}

读取属性Attribute(“”),读取带属性的订单

foreach(XElement element in doc.Root.Descendants(“Items”).Descendants(“OrderItem”))

{

       Console.WriteLine(“商品名:{0},数量:{1}”,element.Attribute(“Name”).Value,element.Attribute(“Count”).Value);

}

 

三、深拷贝和浅拷贝

无论深拷贝还是浅拷贝都重新创建了对象。

实现方式:

浅拷贝 Object.MemberwiseClone

深拷贝通过二进制序列化实现

 

四、特性

(一)   特性是一种允许我们向程序的程序集增加元数据的语言结构。它是用于保存程序结构信息的某种特殊类型的类。

1、将应用了特性的程序结构(program construct)叫做目标(target)。

设计用来获取和使用元数据的程序(比如对象浏览器)被叫做特性的消费者(consumer)。

.NET预定义了很多特性,我们也可以声明自定义特性。

2、我们在源代码中将特性应用于程序结构。

编译器获取源代码并且从特性产生元数据,然后把元数据放到程序集中。

消费者程序可以获取特性的元数据以及程序中其他组件的元数据。注意:编译器同时有生产和消费的特性。

3、大多数特性只针对直接跟随在一个或多个特性片段后的结构。

应用了特性的结构称作被特性装饰(decoratedadorned,两者没有什么区别)。

(二)预定义的保留的特性

1Obsolete特性

Obsolete特性允许我们将程序结构标注为过期的并且在代码编译时显示有用的警告消息。例:

class Program

{

       [Obsolete(“Use method SuperPrintOut”)] //将特性应用到方法

       static void PrintOut(string str)

       {

       Console.WriteLine(str);

}

static void Main(string[] args)

{

       Printout(“Start of Main”); // 调用obsolete方法

}

}

正常输出:Start of Main

但编译器产生CS0618警告通知我们在使用一个过期的结构:

‘AttrObs.Program.PrintOut(string)’ is obsolete:’Use method SuperPrintOut

另一个Obsolete特性的重载接受了bool类型的第二个参数。这个参数指定目标是否应该被标记为错误而不仅是警告:

[Obsolete(“Use method SuperPrintOut” ,true)]

2Conditional特性

Conditional特性允许我们包括或排斥某个特定方法的所有调用。例:

[Conditional(“DoTrace”)]

static void TraceMessage(string str)

{

       Console.WriteLine(str);

}

       当编译器编译这段代码时,会检查是否有一个编译符号被定义为DoTrace(即#define DoTrace)。如果DoTrace被定义,编译器就会像往常一样包含所有对TraceMessage方法的调用。如果没有,编译器就不会输出任何对TraceMessage的调用代码。

(三)其他预定义的特性

CLSCompliant 声明公共暴露的成员应该被编译器检测是否符合CLS。兼容的程序集可以被任何.NET-兼容语言使用。

Serializable 声明结构可以被序列化

NonSerialized 声明结构不能被序列化

DLLImport 声明是非托管代码实现的

WebMethod 声明方法应该被作为XML Web服务的一部分暴露

AttributeUsage 声明特性能应用到什么类型的程序结构。将这个特性应用到特性声明上

(四)自定义特性

1、特性只是某个特殊类型的类。所有特性都派生自System.Attribute

声明一个自定义特性,做如下工作:

       声明一个派生自System.Attribute的类

       给它起一个以后缀Attribute结尾的名字

       为了安全,通常建议声明一个sealed的特性类。例:

public sealed class MyAttributeAttributeSystem.Attribute

{

       …

由于特性持有目标的信息,所有特性类的公共成员只能是:

       字段、属性、构造函数

2、特性构造函数

1)特性和其他类一样,都有构造函数。每一个特性至少必须有一个公共构造函数。

在应用特性时,构造函数的实参必须是在编译期能确定值的常量表达式。

2)比较普通类构造函数的使用和特性的构造函数的使用:

命令语句(普通类):MyClass mc = new MyClass(“Hello”,15);

声明语句(特性):[MyAttribute(“Holds a value”)]

命令语句的实际意义是:“在这里创建新的类”。

声明语句的意义是:“这个特性和这个目标相关联,如果需要构造特性,使用这个构造函数”。

3)构造函数中的位置参数和命名参数

位置参数:编译器根据参数列表中的参数的位置知道哪个实参和哪个形参相匹配,这种参数叫位置参数。

命名参数:用来设置特性的字段或属性的值,由字段或属性名后接等号和初始化值构成。命名参数是实参。

如下代码显示了使用一个位置参数和两个命名参数来应用一个特性:

3、限制特性的使用

AttributeUsage特性可以用来限制特性使用在某个目标类型上。

例:如果我们希望自定义特性MyAttribute只能应用到方法上,可以这样写:

[AttributeUsage(AttributeTarget.Method)]

public sealed class MyAttributeAttribute:System.Attribute

{ …

 

五、自己动手写XML序列化器(XML、反射、特性的综合特性)

(一)需求:将Person对象的AgeNameEmail属性序列化为XML文件

(二)调用预定义XML序列化函数完成任务

XmlSerializer xmlSer = new XmlSerializer(typeof(Person));//创建XmlSerializer对象

using(FileStream fs = File.OpenWrite(“person.xml”))

{

       xmlSer.Serialize(fs,p);//调用Serialize方法

}

(三)自己动手写XmlSerializerSerialize方法

1、要写xml的根节点,根节点是类型的名

将方法命名为DoXmlSerialize(string path,object obj),第一个参数是xml文件的路径,第二个参数是需要Serialize的对象;

obj.GetType()取得对象类型,obj.GetType().Name取得类型名;

新建Xdocument对象,将以类型名命名的XElement对象添加为XdocumentRoot(根节点)。

2、创建这个类型的每个属性的xml节点

PropertyInfo[] pinfos = typeObj.GetProperties();

foreach每个属性获取其CannotSerializable特性,如果有就不能被序列化。

object[] objAttrs = property.GetCustomAttributes(typeof(CanNotSerializableAttribute), false);

对于每个属性都要创建一个xml元素

XElement xElement = new XElement(property.Name, property.GetValue(obj, null));

3、创建CanNotSerializable:Attribute特性,标记不能序列化的属性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值