C#のは、最も一般的な過負荷のコンストラクタのオーバーロード、ToStringメソッドを含む種々の方法である()+演算子オーバーロードできます - * /もオーバーロードできますが、今日我々は演算子のオーバーロードを懸念しています。
I.はじめに
C#が使用して、ユーザ定義型を可能にする オペレータ オーバーロードオペレータ定義のキーワードの静的メンバ関数を。注は、公開によって変更する必要があり、クラスの静的メソッドでなければなりません。しかし、すべての組み込み演算子を表1に、オーバーロードできません。
演算子 | のオーバーロード |
+、 - 、〜、++、 - !、真、偽 | これらのオーバーロードでき単項演算子は、真と偽のオペレータは、ペアをリロードする必要があります |
+、 - 、*、/、%、&、|、^、<<、>> | バイナリ演算子は、リロードしてもよいです |
==、!=、<、>、<=、> = | 比較演算子はオーバーロードでき、ペアでオーバーロードされなければなりません |
&&、|| | 論理演算子を使用することができる、条件をオーバーロードすることはできませんし、過負荷状態にすることができます&|計算します |
[] | 配列インデックス演算子はオーバーロードできませんが、インデクサーを定義することができます |
() | 変換は、演算子をオーバーロードすることはできませんが、新しい変換演算子を定義することができます(暗黙的および明示的な参照) |
+ =、 - =、* =、/ =、%=、&=、| =、^ =、<< =、>> = | ない、明示的な代入演算子のオーバーロード、など+、などの単一のオペレータ、書き換え - 、%を、彼らは暗黙的に書き換えられている場合 |
=、、:?、 - >、、、はsizeof、typeof演算新しいです | これらの演算子はオーバーロードできません |
表1
第二に、声明
オペレータキーワードが構造宣言でクラスまたはオペレータを宣言するために使用されます。演算子の宣言は、以下の4つの形式のものであってもよいです。
-
公共の静的な結果型演算子単項演算子(OP型オペランド)
-
パブリック静的結果型演算子バイナリ演算子(OP型オペランド、OP-TYPE2オペランド2)
-
パブリック静的暗黙オペレータCONV型アウト(CONV-タイプのオペランド)
-
パブリック静的明示オペレータCONV型アウト(CONV-タイプのオペランド)
パラメータ:
結果型:結果の型演算子。
単項演算子:以下のいずれかの演算子:+ - 〜++ - falseにtrueに!
OP-タイプ:最初の(または唯一の)パラメータを入力します。
オペランド:最初の(または唯一の)パラメータの名前。
バイナリ演算子:式中:+ - * /%&| ^ == >> << => <> = <=!
OP-Type2の:二番目のパラメータ。
オペランド2:二番目のパラメータの名前。
コンバージョン型アウト:オペレータの特定の種類の型変換。
CONV型イン:型変換演算子の入力タイプ。
注意:
1、宣言方法をオーバーロード演算子:演算子のキーワードは、コンパイラに伝え、それは実際にオペレータに関連したシンボルに続くオペレータのオーバーロードです。
図2に示すように、オペレータは、refまたはoutパラメータを使用することができないパラメータの値を使用することができます。例では、ノートを参照することができます。
図3に示すように、最初の二つは、組み込み演算子をオーバーロードされた演算子ユーザー定義を宣言する。OP型OP-TYPE2は、およびにその少なくとも一方が密閉型でなければならない(すなわち、オペレータのタイプに属するか、またはカスタム型として理解されます)。例えば、これは、整数加算演算子を再定義妨げます。ノート2つのインスタンスを参照することができます。
図4に示すように、2つの形式が変換演算子を宣言しました。CONV型インと正確に一つのタイプのCONV型アウトを閉じなければならない(すなわち、変換演算子は、その閉じたいくつかの他のタイプに、または閉鎖のいくつかの他のタイプのためにその型から変換タイプができ)。
図5は、二項演算子のために、最初のパラメータは、一般的にLHSを指定し、オペレータ値の左側のオペレータである第二のパラメータは、オペレータの右側の値は、一般指定RHSあります。
図6は、C#は、すべての演算子のオーバーロードが宣言されている必要があり、パブリックと静的、方法があることを意味し、静的クラスでなければならない彼らは、インスタンスに関連付けられていない、自分のクラスや構造に関連しています。
学生のクラス公開 { 公共のint年齢{取得または設定;} パブリック文字列名前{取得または設定;} パブリック学生() {} 公共学生(年齢、文字列名をINT) { ; =年齢this.Ageの this.name =名。 } //構文エラー:無効refとoutパラメータ(refとアウトキーワードを除去することができる)、この文脈では、 公共の静的な学生演算子+(REF学生STU1、学生STU2アウト) { (stu1.Age + STU2新しい新しい学生を返します.Age、stu1.Name + "+++" + stu2.Name); } }
学生のクラス公開 { 公共のint年齢{取得または設定;} パブリック文字列名前{取得または設定;} パブリック学生() {} 公共学生(年齢、文字列名をINT) { ; =年齢this.Ageの this.name =名。 } //エラーをコンパイルします。二項演算子のパラメータの一つであって入力する必要があり(パラメータC1、C2を、学生のタイプが存在することができる) パブリック静的学生演算子+(INT C1、C2のINT) { (新しい新しい学生を返しますC1 + C2、 "暁の初心者"); } }
比較演算子のオーバーロード:
、C#がペアになっオーバーロードされた比較演算子を必要とし、オーバーロード==もオーバーロードされなければならない場合には、!=、またはそれはコンパイルエラーを引き起こします。
Bは、比較演算子は、bool型の値を返す必要があり、他の算術演算子との根本的な違いです。
C、オーバーロード==やで!この方法は、オペレータが同じ論理的等価を実行する必要があり==等しいため=時間、System.Objectから継承された過負荷に等しいべき()とGetHashCodeメソッド()メソッド、またはそれは、コンパイラの警告を引き起こすであろう。
D、C#はオーバーロード可=オペレータは、例えば、過負荷場合+の演算子を、コンパイラが自動的に演算子を使用するオーバーロード+ +演算子=演算子を行います。
E、前回のオペレータ宣言のいずれかが、オプションの属性(C#プログラミングガイド)のリストを持つことができます。
キー:
実際には演算子のオーバーロード、関数のオーバーロード。対応するオペレータ関数呼び出しで指定された最初の演算式は、演算子関数の引数にオペランドは、次に、オーバーロード関数を決定することは、コンパイラによって引数の種類、プロセスに応じて呼び出される必要があります完全な。
パブリッククラスUserControllerで:コントローラー { 公共のActionResultインデックス() { 学生学生=新しい学生(18、 "博客园"); VaRのresultOne =学生+ 3; VAR結果2 =学生+ "晓菜鸟"。 ビューを返します(); } } publicクラスの学生 { 公共のint型年齢{取得します。セット; } パブリック文字列名{得ます。セット; } パブリック学生() {} 公共学生(INT年齢、列名) { this.Age =年齢。 this.Name =名前; } パブリック静的学生演算子+(学生STU、INT C2) { 返す新しい学生(stu.Age + C2、stu.Name + " -晓菜鸟"); } パブリック静的学生演算子+(スチューデントSTU、文字列のサフィックス) { 新しい学生(stu.Age + 11、stu.Name +サフィックス)を返します。 } }
第三に、例
パブリッククラスUserControllerで:コントローラ { 公共のActionResultインデックス() { 文字列メッセージ= String.Emptyを。 学生がstua =新しい学生(1、18、 "晓菜鸟"); 学生スタブ=新しい学生(2、21、 "博客园"); 学生stuC =新しい学生(1、23、 "攻城狮"); メッセージ= stuA.Name +(がstuaがstuCを== "是"? "不是")+ stuC.Name + "<brの/>"; メッセージ+ = stuA.Name +(Stuaの=スタブ"不是":!? "是")+ stuB.Name + "<br />"など。 メッセージ+ =がstua。 ViewData.Model =メッセージ。 ビューを返します(); {int型イド公共取得または設定;} 公共のint年齢{取得または設定;} パブリック文字列名前{取得または設定;} パブリック学生() {} 公共学生(IDはint、int型年齢、文字列名) { this.id = ID; this.Age =年齢; this.name =名; } //オーバーロードのToString()、カスタムフォーマットされた出力 パブリック文字列オーバーライドのToString() { リターン"ID:" + ID + ";名:" +名前+ ";年齢:"年齢+; } } publicクラスの教師 { 公共のint Idを取得または設定;} 公共{文字列の名前を取得または設定;} 私たちのストローク{int型の公共GET、SET;} //オーバーロード演算子「+」、生徒の年齢2つの計算の合計。 パブリック静的学生演算子+(学生LHS、RHS学生) { 新しい新しい学生(0、+ lhs.Ageを返しますrhs.Age、lhs.Name + "と" + rhs.Name); } //演算子のオーバーロード、 " - "、年齢差を計算された2人の学生。 パブリック静的オペレータの学生- (学生LHS、RHSの学生) { リターン新しい学生(0、Math.Abs(lhs.Age - rhs.Age)、lhs.Name + " と" + rhs.Name); } // ==演算子のオーバーロード、同じデフォルトのId学生と同じ人。 BOOL演算子は==静的パブリック(スチューデントLHS、RHS学生) { lhs.Id == rhs.Idを返します。 } //比較演算子はオーバーロードされたペアリングする必要があります。 !パブリック静的ブール演算子=(学生LHS、学生RHS) { 返す(LHS == RHS)!; } }
二項演算子のパラメータの一つに含まれなければならないタイプ:コンパイラエラー、エラー・メッセージを生成する「演算子インスタンスのオーバーロード」。ここでエラー先生のクラスと同じかそれ以下「の注意事項番目のインスタンス」上記の私達と間違っている、と彼は学生が唯一の学生が知っているかわかりませんでした。彼ができない場合のみ、学生が決めることができ、「+ - 」と他の人が決めることができません。オペレータは+関数に対応する、我々は理解することができ、OP-type.operatorに等しい演算子+(OP型オペランド、OP-TYPE2オペランド2)+(オペランド、オペランド2)またはOP-type2.operator +(オペランド、オペランド2) 。
「II例を演算子オーバーロードが」問題ありません、我々はそのような私たちの先生のクラスの教師として、問題をしたい、この時間も行うにはどのように年齢の和と差を見つけると懸念していますか?それだけで、それを書き換えますか?私はあなたが何か良いアイデアや洞察力を持っている場合、内部のコメントにあなたの意見を残す可能性があるだろう!してください展示会は、シャオの新人は大歓迎します!
私はここが継承されると思いますが、サブクラスは親クラスのオーバーロードさを継承してみましょう!「演算子のオーバーロードの三つの例」を参照してください。
UserControllerでクラスパブリック:コントローラ { 公共のActionResultインデックス() { 文字列メッセージ= String.Emptyを、 教師教師TEAA新しい新=(11、30、 "ディレクター劉"、 "監督は教示"); 教師TEABは=新しい新しい教師(12であり、45 "LU教師"、 "アシスタントプリンシパル"); 教師ティアック=新しい新しい教師(11、27、 "劉"、 "小さな第二のクラスの先生"); スチューデントstuOne =新しい新しい学生(1、18、 "暁の新人") ; 学生stuTwo =新しい新しい学生(2、21、 "ブログの庭"); 学生stuThree =新しい新しい学生(1、23、 "包囲のライオン"); = stuOne.Nameメッセージ+(stuOne == stuThree "はい"?: "いいえ")+ stuThree.Name + "<br /> "; メッセージ+ = stuOne.Name +(? stuOne = stuTwo " しない": "はい")+ + stuTwo.Name "<brの/>"; メッセージString.Formatの+ =(「{0}及び{1}年齢合計:<br /> {2} "stuOne.Name、stuThree.Name、stuOne stuThree +); メッセージ= + String.Formatの(" {0}及び{1}年齢差がある:{2} <BR />」、stuOne.Name、stuTwo.Name、stuOne - stuTwo); メッセージ= + stuOne; ViewData.Model =メッセージ; ビューを返す(); } } publicクラスの学生:人物 { パブリック学生() {} 公共学生( IDはint、int型の年齢、文字列名) { this.id ID =; この。年齢=年齢; this.name =名; } //オーバーロードされたのToString()、カスタム書式付き出力。 公共の文字列ToStringメソッドをオーバーライドします() { リターン"ID:" + ID + ";名:" +名+ ";年齢:"年齢+; } } publicクラスの先生:人々 { /// <まとめ>位置</要約> {; SET公共}我々 GET Stringのストローク パブリック教師(){} 公共教師(IDはint、int型の年齢、文字列名、文字列の職務) { this.id ID =; this.Age =年齢; this.name =名; この職務= .Duties; } } //抽象:基底クラスをインスタンス化することができないように抽象クラスが使用され、他の用途は、非抽象クラスを派生する パブリック抽象クラス人 { {int型Idは公共GET、SET;} 公共のint型年齢{GET、SET;} パブリック文字列の名前は{GET、SET;} //オーバーロード演算子"+"は、年齢の合計を計算。 のpublic static int型演算子+(LHS人、 RHS人) { lhs.Age + rhs.Ageを返す; } 。、//演算子のオーバーロード" - "年齢差が計算される、 パブリックstatic int型演算子- (人物LHS、RHS人) { lhs.Age(Math.Absを返します- rhs.Age); } // ==演算子のオーバーロード、同じIDが同じであると考えられる。 パブリック静的BOOL演算子は==(人物LHS、RHS人) { lhs.Id == rhs.Idを返す; } //比較オーバーロード演算子は、対にする必要があります。 !パブリック静的ブール演算子=(人LHS、人々 RHS)が { !返す(LHS == RHS); } }
「演算子のオーバーロードの例IIIは、」ファイル名を指定して実行は、図の結果: