文章目錄
接下來是C#的進階教程了,仍然是雜七雜八並不全面的隨筆。
1. 特性(Attribute)
特性(Attribute)是用於在運行時傳遞程序中各種元素(比如類、方法、結構、枚舉、組件等)的行爲信息的聲明性標籤。您可以通過使用特性向程序添加聲明性信息。
特性(Attribute)用於添加元數據,如編譯器指令和註釋、描述、方法、類等其他信息。
1.1 預定義特性
1.1.1 AttributeUsage
描述瞭如何使用一個自定義特性類。它規定了特性可應用到的項目的類型。語法如下:
[AttributeUsage(
// 規定特性可被放置的語言元素。它是枚舉器 AttributeTargets 的值的組合。默認值是 AttributeTargets.All。
validon,
// allowmultiple(可選的)爲該特性的 AllowMultiple 屬性(property)提供一個布爾值。如果爲 true,則該特性是多用的。默認值是 false(單用的)。
AllowMultiple=allowmultiple,
//inherited(可選的)爲該特性的 Inherited 屬性(property)提供一個布爾值。如果爲 true,則該特性可被派生類繼承。默認值是 false(不被繼承)。
Inherited=inherited
)]
1.1.2 Conditional
這個暫時不瞭解,等後面如果實際需要的時候再補上。。。
1.1.3 Obsolete
標記了不應被使用的程序實體。它可以讓您通知編譯器丟棄某個特定的目標元素。例如,當一個新方法被用在一個類中,但是您仍然想要保持類中的舊方法,您可以通過顯示一個應該使用新方法,而不是舊方法的消息,來把它標記爲 obsolete(過時的)。例如:
class Program
{
/*
* 參數 message,是一個字符串,描述項目爲什麼過時的原因以及該替代使用什麼。
* 參數 iserror,是一個布爾值。如果該值爲 true,編譯器應把該項目的使用當作一個錯誤。默認值是 false(編譯器生成一個警告)。
*/
[Obsolete("不要用舊方法啦",true)]
static void OldMethod() {
Console.WriteLine("這是一箇舊方法");
}
static void NewMethod() {
Console.WriteLine("這是新的方法");
}
static void Main(string[] args)
{
OldMethod();
Console.ReadKey();
}
}
因爲iserror
屬性設置爲了true
,所以在main
方法調用OldMethod
方法時報錯,
1.2 自定義特性
1、創建一個自定義特性:
// 描述如何使用一個自定義特性 SomethingAttribute
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)]
//********自定義特性SomethingAttribute**************//
public class SomethingAttribute : Attribute {
private string name; // 名字
private string data; // 日期
public string Name {
get { return name; }
set { name = value; }
}
public string Data {
get { return data; }
set { data = value; }
}
public SomethingAttribute(string name) {
this.name = name;
this.name = name;
}
}
2、實例化自定義
[Something("Amy", Data = "2018-06-18")]
[Something("Jack", Data = "2018-06-18")]
class Test{}
3、獲取自定義特性的中的變量
Type t = typeof(Test);
var something = t.GetCustomAttributes(typeof(SomethingAttribute),true);
foreach(SomethingAttribute each in something)
{
Console.WriteLine("Name:{0}", each.Name);
Console.WriteLine("Data:{0}",each.Data);
}
2.反射(Reflection)
反射指程序可以訪問、檢測和修改它本身狀態或行爲的一種能力。
2.1 優缺點
優點:
- 1、反射提高了程序的靈活性和擴展性。
- 2、降低耦合性,提高自適應能力。
- 3、它允許程序創建和控制任何類的對象,無需提前硬編碼目標類。
缺點:
- 1、性能問題:使用反射基本上是一種解釋操作,用於字段和方法接入時要遠慢於直接代碼。因此反射機制主要應用在對靈活性和拓展性要求很高的系統框架上,普通程序不建議使用。
- 2、使用反射會模糊程序內部邏輯;程序員希望在源代碼中看到程序的邏輯,反射卻繞過了源代碼的技術,因而會帶來維護的問題,反射代碼比相應的直接代碼更復雜。
2.2 反射的用途
- 它允許在運行時查看特性(attribute)信息。
- 它允許審查集合中的各種類型,以及實例化這些類型。
- 它允許延遲綁定的方法和屬性(property)。
- 它允許在運行時創建新類型,然後使用這些類型執行一些任務。
2.3 使用反射來查看特性(attribute)信息
獲取類和方法特性。
例如:
using System;
using System.Reflection;
namespace BugFixApplication
{
// 一個自定義特性 BugFix 被賦給類及其成員
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]
public class DeBugInfo : System.Attribute
{
private int bugNo;
private string developer;
private string lastReview;
public string message;
public DeBugInfo(int bg, string dev, string d)
{
this.bugNo = bg;
this.developer = dev;
this.lastReview = d;
}
public int BugNo
{
get
{
return bugNo;
}
}
public string Developer
{
get
{
return developer;
}
}
public string LastReview
{
get
{
return lastReview;
}
}
public string Message
{
get
{
return message;
}
set
{
message = value;
}
}
}
[DeBugInfo(45, "Zara Ali", "12/8/2012",
Message = "Return type mismatch")]
[DeBugInfo(49, "Nuha Ali", "10/10/2012",
Message = "Unused variable")]
class Rectangle
{
// 成員變量
protected double length;
protected double width;
public Rectangle(double l, double w)
{
length = l;
width = w;
}
[DeBugInfo(55, "Zara Ali", "19/10/2012",
Message = "Return type mismatch")]
public double GetArea()
{
return length * width;
}
[DeBugInfo(56, "Zara Ali", "19/10/2012")]
public void Display()
{
Console.WriteLine("Length: {0}", length);
Console.WriteLine("Width: {0}", width);
Console.WriteLine("Area: {0}", GetArea());
}
}//end class Rectangle
class ExecuteRectangle
{
static void Main(string[] args)
{
Rectangle r = new Rectangle(4.5, 7.5);
r.Display();
Type type = typeof(Rectangle);
// 遍歷 Rectangle 類的特性
foreach (Object attributes in type.GetCustomAttributes(false))
{
DeBugInfo dbi = (DeBugInfo)attributes;
if (null != dbi)
{
Console.WriteLine("Bug no: {0}", dbi.BugNo);
Console.WriteLine("Developer: {0}", dbi.Developer);
Console.WriteLine("Last Reviewed: {0}",
dbi.LastReview);
Console.WriteLine("Remarks: {0}", dbi.Message);
}
}
// 遍歷方法特性
foreach (MethodInfo m in type.GetMethods())
{
foreach (Attribute a in m.GetCustomAttributes(true))
{
DeBugInfo dbi = (DeBugInfo)a;
if (null != dbi)
{
Console.WriteLine("Bug no: {0}, for Method: {1}",
dbi.BugNo, m.Name);
Console.WriteLine("Developer: {0}", dbi.Developer);
Console.WriteLine("Last Reviewed: {0}",
dbi.LastReview);
Console.WriteLine("Remarks: {0}", dbi.Message);
}
}
}
Console.ReadLine();
}
}
}
運行結果會顯示附加到類 和方法上的自定義特性:
Length: 4.5
Width: 7.5
Area: 33.75
Bug No: 49
Developer: Nuha Ali
Last Reviewed: 10/10/2012
Remarks: Unused variable
Bug No: 45
Developer: Zara Ali
Last Reviewed: 12/8/2012
Remarks: Return type mismatch
Bug No: 55, for Method: GetArea
Developer: Zara Ali
Last Reviewed: 19/10/2012
Remarks: Return type mismatch
Bug No: 56, for Method: Display
Developer: Zara Ali
Last Reviewed: 19/10/2012
Remarks:
3. 屬性(Property)
屬性(Property) 是類(class)、結構(structure)和接口(interface)的命名(named)成員。類或結構中的成員變量或方法稱爲 域(Field)。屬性(Property)是域(Field)的擴展,且可使用相同的語法來訪問。它們使用 訪問器(accessors) 讓私有域的值可被讀寫或操作。
看起來很複雜,其實從下面這個例子就可以直觀地瞭解到什麼是屬性啦:
// 聲明類型爲 string 的 Code 屬性
public string Code
{
get
{
return code;
}
set
{
code = value;
}
}
在上面一個例子中,Code就是一個屬性,get 、 set就是訪問器。
3.1 抽象屬性
抽象類可擁有抽象屬性,這些屬性應在派生類中被實現。
public abstract class Person
{
public abstract string Name
{
get;
set;
}
public abstract int Age
{
get;
set;
}
}
在派生類中:
class Student : Person
{
private string name = "N.A";
private int age = 0;
// 聲明類型爲 string 的 Name 屬性
public override string Name
{
get
{
return name;
}
set
{
name = value;
}
}
// 聲明類型爲 int 的 Age 屬性
public override int Age
{
get
{
return age;
}
set
{
age = value;
}
}
public override string ToString()
{
return "Name = " + Name + ", Age = " + Age;
}
}
4. 索引器(Indexer)
索引器(Indexer) 允許一個對象可以像數組一樣被索引。當您爲類定義一個索引器時,該類的行爲就會像一個 虛擬數組(virtual array) 一樣。您可以使用數組訪問運算符([ ])來訪問該類的實例。