C#特性之通俗演义

  首先要说的是,可能一些刚接触C#的朋友常常容易把属性(Property)跟特性(Attribute)弄混淆,其实这是两种不同的东西。属性就是面向对象思想里所说的封装在类里面的数据字段,其形式为:

 

    public class HumanBase
    {
        
public String Name { getset; }
        
public int Age { getset; }
        
public int Gender { getset; }
    }

 

 

在HumanBase这个类里出现的字段都叫属性(Property),而C#特性(Attribute)又是怎样的呢?

 

    [Serializable]
    
public class HumanBase
    {
        
public String Name { getset; }
        
public int Age { getset; }
        
public int Gender { getset; }
    }

 

 

    简单地讲,我们在HumanBase类声明的上一行加了一个[Serializable],这就是特性(Attribute),它表示HumanBase是可以被序列化的,这对于网络传输是很重要的,不过你不用担心如何去理解它,如何理解就是我们下面要探讨的。

 

    C#特性可以应用于各种类型和成员。前面的例子将特性用在类上就可以被称之为“类特性”,同理,如果是加在方法声明前面的就叫方法特性。无论它们被用在哪里,无论它们之间有什么区别,特性的最主要目的就是自描述。并且因为特性是可以由自己定制的,而不仅仅局限于.NET提供的那几个现成的,因此给 C#程序开发带来了相当大的灵活性和便利。

我们还是借用生活中的例子来介绍C#的特性机制吧。

 

    假设有一天你去坐飞机,你就必须提前去机场登机处换登机牌。登机牌就是一张纸,上面写着哪趟航班、由哪里飞往哪里以及你的名字、座位号等等信息,其实,这就是特性。它不需要你生理上包含这些属性(人类出现那会儿还没飞机呢),就像上面的HumanBase类没有IsSerializable这样的属性,特性只需要在类或方法需要的时候加上去就行了,就像你不总是在天上飞一样。

当我们想知道HumanBase是不是可序列化的,可以通过:

 

        protected void Page_Load(object sender, EventArgs e)
        {
            Response.Write(
typeof(HumanBase).IsSerializable);
        }

 

 

    拿到了登机牌,就意味着你可以合法地登机起飞了。但此时你还不知道你要坐的飞机停在哪里,不用担心,地勤人员会开车送你过去,但是他怎么知道你是哪趟航班的呢?显然还是通过你手中的登机牌。所以,特性最大的特点就是自描述。

既然是起到描述的作用,那目的就是在于限定。就好比地勤不会把你随便拉到一架飞机跟前就扔上去了事,因为标签上的说明信息就是起到限定的作用,限定了目的地、乘客和航班,任何差错都被视为异常。如果前面的HumanBase不加上Serializable特性就不能在网络上传输。

我们在顺带来介绍一下方法特性,先给HumanProperty加上一个Run方法:

 

ExpandedBlockStart.gif代码
 [Serializable]
    
public class HumanPropertyBase
    {
        
public string Name { getset; }
        
public int Age { getset; }
        
public int Gender { getset; }
        
public void Run(int speed)
        { 
           
// Running is good for helath;
        }
    }

 

 

        只要是个四肢健全、身体健康的人就可以跑步,那这么说,跑步就是有前提条件的,至少是四肢健全,身体健康。由此可见,残疾人和老年人如果跑步就会出问题。假设一个HumanBase的对象代表的是一位耄耋老人,如果让他当刘翔的陪练,那就直接光荣了。如何避免这样的情况呢,我们可以在Run方法中加一段逻辑代码,先判断Age大小,如果小于2或大于60直接抛异常,但是2-60岁之间也得用Switch来分年龄阶段地判断speed参数是否合适,那么逻辑就相当臃肿。简而言之,如何用特性表示一个方法不能被使用呢?OK, here we go:

 

ExpandedBlockStart.gif代码
 [Obsolete("I'm so old,don't kill me!"true)] //标记不再使用的程序元素。无法继承此类。该布尔值指示是否将使用已过时的元素视为错误。
        public virtual void Run(int speed)
        { 
           
// Running is good for helath;
        }

 

 

    上面大致介绍了一下特性的使用与作用,接下来我们要向大家展示的是如何通过自定义特性来提高程序的灵活性,如果特性机制仅仅能使用.NET提供的那几种特性,不就太不过瘾了么。

首先,特性也是类。不同于其它类的是,特性都必须继承自System.Attribute类,否则编译器如何知道谁是特性谁是普通类呢。当编译器检测到一个类是特性的时候,它会识别出其中的信息并存放在元数据当中,仅此而已,编译器并不关心特性说了些什么,特性也不会对编译器起到任何作用,正如航空公司并不关心每个箱子要去哪里,只有箱子的主人和搬运工才会去关心这些细节。假设我们现在就是航空公司的管理人员,需要设计出前面提到的登机牌,那么很简单,我们先看看最主要的信息有哪些:

 

ExpandedBlockStart.gif代码
    public class BoardingCheckAttribute:System.Attribute
    {
        
public string ID
        {
            
get;
            
private set;
        }

        
public string Name
        {
            
get;
            
private set;
        }

        
public int FlightNumber
        {
            
get;
            
private set;
        }

        
public int PositionNumber
        {
            
get;
            
private set;
        }

        
public string Departure
        {
            
get;
            
private set;
        }

        
public string Destination
        {
            
get;
            
private set;
        }
    }

 

 

    我们简单列举这些属性作为航空公司登机牌上的信息,用法和前面的一样,贴到HumanBase上就行了,说明此人具备登机资格。这里要简单提一下,你可能已经注意到了,在使用BoardingCheckAttribute的时候已经把Attribute省略掉了,不用担心,这样做是对的,因为编译器默认会自己加上然后查找这个属性类的。哦,等一下,我突然想起来他该登哪架飞机呢?显然,在这种需求下,我们的特性还没有起到应有的作用,我们还的做点儿工作,否则乘客面对一张空白的机票一定会很迷茫。

 

   于是,我们必须给这个C#特性加上构造函数,因为它不仅仅表示登机的资格,还必须包含一些必要的信息才行:

 

ExpandedBlockStart.gif代码
  public BoardingCheckAttribute(string id,string name,int flightNumber,int positionNumber,string departure,string destination)
        {
            
this.ID = id;
            
this.Name = name;
            
this.FlightNumber = flightNumber;
            
this.PositionNumber = positionNumber;
            
this.Departure =departure;
            
this.Destination = destination;
        }

 

 OK,我们的乘客就可以拿到一张正式的登机牌登机了,have a good flight!

 

ExpandedBlockStart.gif代码
    [BoardingCheck("11","张三",1001,2002,"杭州","台湾")]
    
public class HumanPropertyBase
    {
        
public string Name { getset; }
        
public int Age { getset; }
        
public int Gender { getset; }

    }

    
public class BoardingCheckAttribute:System.Attribute
    {

        
public BoardingCheckAttribute(string id,string name,int flightNumber,int positionNumber,string departure,string destination)
        {
            
this.ID = id;
            
this.Name = name;
            
this.FlightNumber = flightNumber;
            
this.PositionNumber = positionNumber;
            
this.Departure =departure;
            
this.Destination = destination;
        }

        
public string ID
        {
            
get;
            
private set;
        }

        
public string Name
        {
            
get;
            
private set;
        }

        
public int FlightNumber
        {
            
get;
            
private set;
        }

        
public int PositionNumber
        {
            
get;
            
private set;
        }

        
public string Departure
        {
            
get;
            
private set;
        }

        
public string Destination
        {
            
get;
            
private set;
        }
    }

    
public partial class WebForm1 : System.Web.UI.Page
    {
        
protected void Page_Load(object sender, EventArgs e)
        {
            BoardingCheckAttribute boradingCheck 
= null;

            
object[] customAttributes = typeof(HumanPropertyBase).GetCustomAttributes(true);

            
foreach (var attribute in customAttributes)
            {
                
if (attribute is BoardingCheckAttribute)
                {
                    boradingCheck 
= attribute as BoardingCheckAttribute;

                    Response.Write(boradingCheck.Name
+"'s ID is "
                     
+boradingCheck.ID+",he/she wants to "+
                     boradingCheck.Destination
+" from "+
                     boradingCheck.Departure
+" by the plane "
                     
+boradingCheck.FlightNumber+
                     
",his/her position is "+boradingCheck.PositionNumber+"."
                     );
                }
            }
        }
    }

 

 

转载于:https://www.cnblogs.com/jhxk/articles/1739249.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/379230.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

栈应用_计算按运算符优先级分布的算式(代码、分析、汇编)

目录&#xff1a;代码&#xff1a;分析&#xff1a;汇编&#xff1a;代码&#xff1a; LinkList.h LinkList.c LinkStack.h LinkStack.c 栈-线性表 main.c #include <stdio.h> #include "LinkStack.h"//该程序用栈来计算算式 /*比如&#xff1a;1*56/(5-3)…

栈应用_将算式转成按运算符优先级分布(代码、分析、汇编)

目录&#xff1a;代码&#xff1a;分析&#xff1a;汇编&#xff1a;代码&#xff1a; LinkList.h LinkList.c LinkStack.h LinkStack.c 栈-线性表 main.c #include <stdio.h> #include "LinkStack.h"/* 该程序将 正常的算式 转换成按照运算符优先分布的算式…

课堂笔记(一)

1&#xff0c;怎样查询函数的用法 help(函数名) 2&#xff0c;表达式float(0b1100010101)float(0o1425)float(0x315)的结果是什么&#xff0c;并说明原因 True 浮点类型的数用二进制八进制十六进制的不同表达 3&#xff0c;oct()方法 转换八进制输出 4&#xff0c;hex()方…

[转]深入浅出Java设计模式之备忘录模式

本文转自&#xff1a;http://dev.yesky.com/450/2070450.shtml 一、引子   俗话说&#xff1a;世上难买后悔药。所以凡事讲究个“三思而后行”&#xff0c;但总常见有人做“痛心疾首”状&#xff1a;当初我要是……。如果真的有《大话西游》中能时光倒流的“月光宝盒”&#…

递归问题(代码、分析、汇编)

目录&#xff1a;代码&#xff1a;分析&#xff1a;汇编&#xff1a;代码&#xff1a; main.c #include <stdio.h>//该程序使用递归将字符串从后往前依次输出void reverse(char* s) {if( (s ! NULL) && (*s ! \0) ){reverse(s 1);printf("%c", *s);…

递归-裴波那契数列(代码、分析、汇编)

目录&#xff1a;代码&#xff1a;分析&#xff1a;汇编&#xff1a;代码&#xff1a; main.c #include <stdio.h>//该程序输出裴波那契数列 int fibonacci(int n) {if( n > 1 ){return fibonacci(n-1) fibonacci(n-2);//注意&#xff1a;这里调用是一直调用左边函…

经典例题(一)

1&#xff0c;已知复数 x 6 8j 请写出它的模、实部、虚部及共轭复数的命令&#xff0c;并写出运行结果。 X 6 8j print("模为:%d"% abs(X)) print("实部为:%s"% X.real) print("虚部为:%s"% X.imag) print("共轭复数为:%s"% X.co…

递归-汉诺塔(代码、分析、汇编)

代码&#xff1a; #include <stdio.h>void hanoi(int n, char a, char b, char c) {if( n > 0 ){if( n 1 ){printf("%c -> %c\n", a, c);}else{hanoi(n-1, a, c, b);printf("%c -> %c\n", a, c);hanoi(n-1, b, a, c);}} }int main() {han…

if语句(四)

1&#xff0c;简单if示例 phones [iphone,xiaomi,huawei,smartisan] for phone in phones:if phone huawei:print(phone.upper())#将字符串的所有字母大写else:print(phone.title())#将字符串中的每个单词的首字符大写效果图如下&#xff1a; 2&#xff0c;if条件测试 ph…

welcome to my blog

转载于:https://www.cnblogs.com/jiangjun/archive/2012/10/22/2734600.html

递归-输出字符串所有的组合情况(代码、分析、汇编)

目录&#xff1a;代码&#xff1a;分析&#xff1a;汇编&#xff1a;代码&#xff1a; #include <stdio.h>/*程序描述&#xff1a;输出字符串所有的组合情况使用permutation函数进行将指定的下标值&#xff0c;与最大下标值这个范围的每个下标值进行交换每调用一次permu…

递归-计算字符串长度(代码、分析、汇编)

目录&#xff1a;代码&#xff1a;分析&#xff1a;汇编&#xff1a;代码&#xff1a; main.c #include <stdio.h>//该程序用递归计算字符串长度int strlen(const char* s) {if( s NULL ){return -1;}else if( *s \0 ){return 0;}else{return strlen(s1) 1;} }int m…

Python-杨辉三角

在控制台输出如图所示一个8层的杨辉三角。 杨辉三角介绍&#xff1a; 每个数等于它上方两数之和 每行数字左右对称&#xff0c;由1开始逐渐变大 第n行的数字有n项&#xff0c;将n取8 def yanghui(n):l[1,1]for x in range(1,n):for a in range(x):l[a]l[a]l[a1]l.insert(0,1)…

如何向妻子解释OOD(转)

前言 此文译自CodeProject上<How I explained OOD to my wife>一文&#xff0c;该文章在Top Articles上排名第3&#xff0c;读了之后觉得非常好&#xff0c;就翻译出来&#xff0c;供不想读英文的同学参考学习。 作者(Shubho)的妻子(Farhana)打算重新做一名软件工程师(她…

不安全代码和指针资料汇编

不安全代码和指针&#xff08;C# 编程指南&#xff09;为了保持类型安全&#xff0c;默认情况下&#xff0c;C# 不支持指针运算。不过&#xff0c;通过使用 unsafe 关键字&#xff0c;可以定义可使用指针的不安全上下文。有关指针的更多信息&#xff0c;请参见主题指针类型。 注…

ffmpeg-从flv文件中提取AAC音频数据保存为文件

AAC ADTS格式协议&#xff1a; 从flv文件中提取AAC音频数据保存为文件。 如果需要详细了解AAC ADTS格式&#xff0c;可以查询文档。 原文件&#xff1a; 提取aac文件&#xff1a; main.c #include <stdio.h> #include <libavutil/log.h>> #include <lib…

N Queen(代码、分析、汇编)

目录&#xff1a;代码&#xff1a;分析&#xff1a;汇编&#xff1a;代码&#xff1a; main.c #include <stdio.h>/* 程序描述&#xff1a;输出N*N中符合左右对角线与上下左右方向都没被使用的位置在每一行的所有情况使用检测左上角&#xff0c;正上角&#xff0c;右上…

Python-身份证核对

中华人民共和国居民身份证号码由17 位数字和1位校验码组成。其中&#xff0c;前6位为所在地编号&#xff0c;第7~14 位为出生年月日&#xff0c;第15~17位为登记流水号&#xff0c;其中第17位偶数为女性&#xff0c;奇数为男性。校验码的生成规则如下: 将前面的身份证号码17位数…

树存储结构(代码、分析、汇编)

目录&#xff1a;代码&#xff1a;分析&#xff1a;汇编&#xff1a;代码&#xff1a; LinkList.h LinkList.c 线性表 GTree.h #ifndef _GTREE_H_ #define _GTREE_H_typedef void GTree;//定义树类型 typedef void GTreeData;//定义节点中存放数据的类型 typedef void (GTre…

二元矩阵峰值搜索_好斗的牛(二元搜索)

二元矩阵峰值搜索A farmer has built a long barn with N stalls. The stalls are placed in a straight manner at positions from x1, x2, ...xN. But his cows (C) are aggressive and don’t want to be near other cows. To prevent cows from hurting each other, he wan…