Effective C# Item24:聲明式編程優於命令式編程

來源:互聯網
上載者:User

    聲明式編程是一種更簡單、更精練的描述軟體程式行為的方式,它意味著可以使用聲明、而非指令的方式來定義程式的行為。C#中大部分編程都是命令式編程,即通過編寫方法來定義程式的行為。我們可以通過使用特性,來在C#中實現聲明式編程,它更易於實現、閱讀和維護。

    .NET架構本身已經為我們提供了大量的特性,我們可以利用這些特性非常方便的實現聲明式編程;當.NET架構提供的特性不能滿足我們的需求時,我們也可以自己定製特性。

    首先,我們來看一個使用.NET架構提供的特性的例子,看以下代碼。

代碼

1     public class ClassWithAttribute
2 {
3 [Conditional("DEBUG")]
4 [Obsolete("This Method should not be called yet.")]
5 public void Ouput()
6 {
7 Console.WriteLine("Hello World");
8 }
9 }

    上面的代碼使用了兩個特性,第一個特性Conditional,表明方法只在DEBUG模式下才會被調用;第二個特性Obsolete,表明方法已經被廢棄,不應該再調用,這兩個特性都是.NET架構提供的,我們可以很方便的使用它們。

    然後,我們來看一個自己定製特性的例子,看以下代碼。

代碼

    [AttributeUsage(AttributeTargets.All)]
public class TestAttribute : System.Attribute
{
private string m_strOutputField;
public string OutputField
{
get { return m_strOutputField; }
set { m_strOutputField = value; }
}

public TestAttribute(string fielaName)
{
m_strOutputField = fielaName;
}
}


[Test("Name")]
public class Employee
{
private string m_strName;
public string Name
{
get { return m_strName; }
set { m_strName = value; }
}

private string m_strSex;
public string Sex
{
get { return m_strSex; }
set { m_strSex = value; }
}

private string m_strAddress;
public string Address
{
get { return m_strAddress; }
set { m_strAddress = value; }
}

public Employee(string name, string sex, string address)
{
m_strName = name;
m_strSex = sex;
m_strAddress = address;
}
}

    上述代碼中,定義了一個特性,名為TestAttribute,它派生自System.Attribute,包含一個名為OutputField的屬性,然後定義了一個用於表示員工資訊的類,包含Name、Sex和Address三個屬性,其中,這個類被Test特性所修飾,特性建構函式中的值是“Name”。

    下面是測試函數。

代碼

 1     private static void OutputEmpInfo()
2 {
3 Employee emp = new Employee("Wing", "M", "BeiJing");
4 //get attribute info.
5   object[] arrAttribute = typeof(Employee).GetCustomAttributes(typeof(TestAttribute), false);
6 string strFieldName = string.Empty;
7 if (arrAttribute != null && arrAttribute.Length > 0)
8 {
9 TestAttribute attribute = arrAttribute[0] as TestAttribute;
10 strFieldName = attribute.OutputField;
11 }
12 if (string.IsNullOrEmpty(strFieldName))
13 {
14 return;
15 }
16 //get property by reflection.
17   PropertyInfo propInfo = typeof(Employee).GetProperty(strFieldName);
18 if (propInfo == null)
19 {
20 return;
21 }
22 //output value.
23   object outputValue = propInfo.GetValue(emp, null);
24 Console.WriteLine(outputValue.ToString());
25 }

    上述代碼中,首先定義了一個Employee類型的對象,然後尋找Employee類型中Test特性的資訊,並將特性的OutputField屬性返回,然後通過反射,取得Employee類型對象中的資訊,將其輸出。

    當我們將特性中的OutputField屬性設定為“Name”時,程式會輸出Employee對象的Name屬性,當我們將特性的OutputField屬性設定為“Sex”或者“Address”時,程式會輸出Employee對象對應的屬性的值。

    當一個簡單的聲明就可以表明我們的意圖時,採用聲明式的方法可以避免重複性代碼。如果針對某一種功能,在程式中只需要一兩次,那麼編寫一些簡單的函數就可以了,如果這些功能是在大量的地方都需要使用,那麼通過演算法加聲明式的解決方案將會為我們節省大量的時間和精力。

 

    總結:聲明式編程是一個強大的工具,當可以使用特性來聲明我們的意圖時,實際上也就避免了在多個類似的手工編寫的演算法中,犯邏輯錯誤的可能。聲明式編程會建立更為可讀和清晰的代碼。這意味著更少的錯誤。如果可以使用.NET架構中定義的特性,那麼我們就應該積極的使用。如果不能,則可以考慮選擇建立我們自己的屬性類別,然後再將來使用它建立相同的行為。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.