2020年09月08日
川俣晶の縁側ソフトウェアC# コーディング How To total 1087 count

【入門級】同じオブジェクトに含まれる同じ名前のメソッドを使い分ける

Written By: 川俣 晶連絡先

同じ名前のメソッドを作る方法 §

 一つのオブジェクトに同じ名前のメソッドを作ることは可能です。

 最も簡単な方法は引数の型や数を変えてしまうことです。

 しかし、引数が同一でも同じ名前のメソッドを1つのオブジェクトに複数持たせることができます。

 それには継承を使用します。

 あるクラスにメソッドを定義し、そのクラスを継承したクラスにまた同じ名前のメソッドを記述します。

 しかし、これは通常エラーになります。

 後者のメソッドにnewキーワードを付けて、明示的な置き換えを示すことで記述可能になります。サンプルソースのinternal new void MyMethodA()という部分のnewキーワードです。

2つのメソッドを呼び分ける方法 §

 では2つの同じ名前のメソッドがあるとして、それらを意識的に呼び分けることはできるのでしょうか。

 できます。

 呼び出す場合のオブジェクトの型を変えれば良いのです。このとき、クラスA型から呼び出すとクラスAのメソッド、クラスB型から呼び出すとクラスBのメソッドになります。

 型の変換はできるのでしょうか?

 できます。

 クラスAを継承して定義されたクラスBであれば、インスタンスをクラスA型に変換できます。変換してもオブジェクトは元のままです。ですから再びクラスB型に戻すこともできます。

 これで意識的に使い分けることができます。

避けた方が賢明 §

 しかし、このような使い分けはトラブルの元なので、できればこういうテクニックは使わない方が得策です。

 それにも関わらず利用せざるを得なくなることもあるので、知っておくと価値があるテクニックです。

罠の数々 §

  • 抽象メソッドまたは仮想メソッドとして作成し、これをnewではなくoverrideキーワードで置き換えた場合、呼び出す型に関係なく最後に置き換えたメソッドの内容が常に実行される。この場合は同じ名前のメソッドの使い分けができない
  • キーワードnewは、綴りがnew演算子と同じため、情報の検索が混乱しがち (実は筆者が試したとき、Visual Studioでnewキーワードにキャレットを置いてF1を押したらnew演算子の説明ページに飛んでしまった)
  • 利用例が少ないので、そもそも情報が得にくい
  • それにも関わらず知識としては知っておく必要がある (たとえ利用頻度が極端に低くても)

参考リンク §

new modifier (C# Reference)

virtual (C# Reference)

override (C# Reference)

リポジトリ §

https://github.com/autumn009/cshowto

SameNameMethod §

using System;

class Program

{

    class A

    {

        // 通常メソッド

        internal void MyMethodA()

        {

            Console.WriteLine("I'm MyMethodA in class A.");

        }

        // 仮想メソッド

        internal virtual void MyMethodB()

        {

            Console.WriteLine("I'm MyMethodB in class A.");

        }

    }

    class B : A

    {

        // new付きメソッド

        internal new void MyMethodA()

        {

            Console.WriteLine("I'm MyMethodA in class B.");

        }

        // override付きメソッド

        internal override void MyMethodB()

        {

            Console.WriteLine("I'm MyMethodB in class B.");

        }

    }

    static void Main()

    {

        // objは型B

        B obj = new B();

        // objTypeAは型A (中味は同じ)

        A objTypeA = obj;

        obj.MyMethodA();

        objTypeA.MyMethodA();

        obj.MyMethodB();

        objTypeA.MyMethodB();

    }

}

実行結果

I'm MyMethodA in class B.

I'm MyMethodA in class A.

I'm MyMethodB in class B.

I'm MyMethodB in class B.

(メソッドMyMethodAは使い分け可能。MyMethodBは使い分けできない)

COOL C# CREW

C#ハウツー連載の解説増量、カラーのソース、新規書き下ろし追加の読みやすい単行本はこちら。

C#ハウツー: 逆引き入門・こんな機能はどう書くの?