『白話C#』


まず、C#に触れたばかりの友人は、属性(Property)と特性(Attribute)を混同しやすいかもしれませんが、実はこれは2つの異なるものです.属性とは、クラスにカプセル化されたデータフィールドであり、その形式は次のとおりです.
   1:
 public
 class
 HumanBase
   2:
 {
   3:
     public
 string
 Name { get; set; }
   4:
     public
 int
 Age { get; set; }
   5:
     public
 int
 Gender { get; set; }
   6:
 }

HumanBaseというクラスに現れるフィールドは属性(Property)と呼ばれていますが、特性(Attribute)はどうでしょうか.
   1:
 [Serializable]
   2:
 public
 class
 HumanBase
   3:
 {
   4:
     public
 string
 Name { get; set; }
   5:
     public
 int
 Age { get; set; }
   6:
     public
 int
 Gender { get; set; }
   7:
 }

簡単に言えば、HumanBaseクラスの宣言の前の行に[Serializable]を追加しました.これが特性(Attribute)です.これはHumanBaseがシーケンス化できることを示しています.これはネットワーク伝送にとって重要ですが、どのように理解するか心配しないでください.どのように理解するかは、私たちが次に検討します.
C#のプロパティは、さまざまなタイプとメンバーに適用できます.前述の例では,クラスに特性を用いることを「クラス特性」と呼ぶことができ,同様に,メソッド宣言に加わる前のものをメソッド特性と呼ぶ.それらがどこで使用されても、それらの違いにかかわらず、特性の最も主要な目的は自己記述である.また、特性は、限定するものではなく、独自にカスタマイズすることができる.NETが提供するいくつかの既存のものは、C#プログラムの開発にかなりの柔軟性と便利さをもたらしています.
私たちはやはり生活の例を借りてC#の特性メカニズムを紹介しましょう.
ある日飛行機に乗るとしたら、早めに空港の搭乗所に行って搭乗券を交換しなければなりません.搭乗券は1枚の紙で、どのフライト、どこからどこへ行くか、あなたの名前、座席番号などの情報が書かれていますが、実は、これが特性です.それはあなたが生理的にこれらの属性を含む必要はありません(人類が現れた時はまだ飛行機がありません)、上のHumanBase類にはIsSerializableのような属性がありません.特性はクラスや方法が必要なときに加えるだけでいいです.あなたがいつも空を飛んでいないように.
HumanBaseがシーケンス化可能かどうかを知りたい場合は、次のようにします.
   1:
 static
 void
 Main(string
[] args)
   2:
 {
   3:
     Console.WriteLine(typeof
(HumanBase).IsSerializable);
   4:
  
   5:
     Console.ReadLine();
   6:
 }

搭乗券を手に入れると、合法的に搭乗して離陸できることを意味します.しかし、この时あなたはまだあなたが乗る飛行機がどこに止まっているか分からないので、心配しないでください.地勤員は車で送ってくれますが、彼はどうしてあなたがどのフライトなのか知っていますか.明らかにあなたの手の中の搭乗券を通ります.したがって,特性の最大の特徴は自己記述である.
説明の役割を果たす以上、その目的は限定することである.例えば、地勤はあなたを勝手に飛行機の前に引っ張って投げつけることはありません.ラベルの説明情報は限定的な役割を果たしているので、目的地、乗客、フライトを限定し、どんな間違いも異常と見なされています.前のHumanBaseにSerializable特性を加えないとネットワーク上で伝送できない.
まずHumanPropertyにRunメソッドを追加します.
   1:
 [Serializable]
   2:
 public
 class
 HumanPropertyBase
   3:
 {
   4:
     public
 string
 Name { get; set; }
   5:
     public
 int
 Age { get; set; }
   6:
     public
 int
 Gender { get; set; }
   7:
  
   8:
     public
 void
 Run(int
 speed)
   9:
     {
  10:
         // Running is good for health.
  11:
     }
  12:
 }

四肢が健全で、体が健康な人であれば走ることができます.そう言えば、走るには前提条件があります.少なくとも四肢が健全で、体が健康です.このように、障害者や高齢者が走ると問題が発生する.HumanBaseの相手が老人を代表していると仮定すると、劉翔の練習をさせてくれれば、直接光栄だ.このような状況を回避するには,Run法に論理コードを付けてAgeサイズを判断し,2歳未満または60歳以上であれば直接投げ異常であるが,2−60歳の間でもSwitchを用いてspeedパラメータが適切か否かを年齢段階的に判断しなければならず,論理はかなり肥大化している.簡単に言えば、一つの方法が使用できないことを特性で表すにはどうすればいいのでしょうか.OK, here we go:
   1:
 [Obsolete("I'm so old, don't kill me!"
, true
)]
   2:
 public
 virtual
 void
 Run(int
 speed)
   3:
 {
   4:
     // Running is good for health.
   5:
 }

以上、特性の使用と役割を大まかに紹介したが、次に、特性メカニズムが使用できるだけであれば、特性をカスタマイズすることでプログラムの柔軟性を高める方法を示したい.NETが提供するいくつかの特性は、あまりにも中毒ではないでしょうか.
まず、特性もクラスです.他のクラスとは異なり、特性はSystemから継承する必要がある.Attributeクラス、そうでなければコンパイラはどのようにして誰が特性で誰が普通のクラスなのかを知っていますか.コンパイラがクラスが特性であることを検出すると、その中の情報を識別してメタデータに格納します.それだけで、コンパイラは特性が何を言ったのか気にしません.特性もコンパイラに何の役割も果たしません.航空会社が箱ごとにどこに行くのか気にしないように、箱の主人と運搬業者だけがこれらの詳細に関心を持っています.もし私たちが今航空会社の管理者であるとしたら、前に述べた搭乗券を設計する必要があります.それは簡単です.まず、最も主要な情報を見てみましょう.
   1:
 public
 class
 BoardingCheckAttribute : Attribute
   2:
 {
   3:
     public
 string
 ID { get; private
 set; }
   4:
     public
 string
 Name { get; private
 set; }
   5:
     public
 int
 FlightNumber { get; private
 set; }
   6:
     public
 int
 PostionNumber { get; private
 set; }
   7:
     public
 string
 Departure { get; private
 set; }
   8:
     public
 string
 Destination { get; private
 set; }
   9:
 }

これらの属性を航空会社の搭乗券の情報として簡単に列挙し、使い方は前と同じようにHumanBaseに貼ればいいので、この人が搭乗資格を持っていることを説明します.ここで簡単に言えば、BoardingCheckAttributeを使用するときにAttributeを省略していることに気づいたかもしれません.心配しないでください.これは正しいです.コンパイラはデフォルトで自分で追加してこの属性クラスを検索するからです.ああ、ちょっと待って、私は突然彼がどの飛行機に乗るべきか思い出しました.明らかに、このような需要の下で、私たちの特性はまだあるべき役割を果たしていません.私たちはまだ仕事をしています.そうしないと、乗客は空白の航空券に直面してきっと迷っています.
そこで、搭乗資格だけでなく、必要な情報も含まなければならないので、この特性に構造関数を追加する必要があります.
   1:
 public
 BoardingCheckAttribute(string
 id, string
 name, string
 flightNumber, string
 positionNumber, string
 departure, string
 destination)
   2:
 {
   3:
     this
.ID = id;
   4:
     this
.Name = name;
   5:
     this
.FlightNumber = flightNumber;
   6:
     this
.PositionNumber = positionNumber;
   7:
     this
.Departure = departure;
   8:
     this
.Destination = destination;
   9:
 }

 
OK、私たちの乗客は正式な搭乗券を手に入れて搭乗することができます.have a good flight!
   1:
 static
 void
 Main(string
[] args)
   2:
 {
   3:
     BoardingCheckAttribute boardingCheck = null
;
   4:
     object
[] customAttributes = typeof
(HumanPropertyBase).GetCustomAttributes(true
);
   5:
  
   6:
     foreach
 (var attribute in
 customAttributes)
   7:
     {
   8:
         if
 (attribute is
 BoardingCheckAttribute)
   9:
         {
  10:
             boardingCheck = attribute as
 BoardingCheckAttribute;
  11:
  
  12:
             Console.WriteLine(boardingCheck.Name
  13:
                         + "'s ID is "
  14:
                         + boardingCheck.ID
  15:
                         + ", he/she wants to "
  16:
                         + boardingCheck.Destination
  17:
                         + " from "
  18:
                         + boardingCheck.Departure
  19:
                         + " by the plane "
  20:
                         + boardingCheck.FlightNumber
  21:
                         + ", his/her position is "
  22:
                         + boardingCheck.PositionNumber
  23:
                         + "."
);
  24:
         }
  25:
     }
  26:
  
  27:
     Console.ReadLine();
  28:
 }