いっしきまさひこBLOG

AI・機械学習関連、Web制作関連、プログラミング関連、旅行記録などなど。一色政彦。

メソッドのシグネチャ(signature)とメソッドの構文(syntax)の違い

signature syntaxメソッドの「シグネチャ」(signature)という用語は、メソッドの定義を示す際によく使われる用語ですが、厳密な意味を考えると、この用語を使用する際には注意を要します。シグネチャは、プログラミング言語設計の用語で、言語ごとに明確な意味が定義されているからです。その意味を正しく把握したうえで「シグネチャ」という用語を使う必要があるのです。

一方の「構文」(syntax)という用語は、より汎用的な意味で使われます。単に「ソース コード上にどのように文字が配列されているか」という表記方法を表しているだけなので、プログラミング言語ごとに意味合いが異なるわけではありません。

従って、無難にメソッドの定義について言及したい場合は、「メソッド構文」という用語を使った方がよいと思います。

以下ではメソッドの「シグネチャ」についてもう少し詳しく解説しましょう。

まずはシグネチャの一般的な意味について、次にC#言語やVisual Basic言語(以下、C#/VB言語)における意味について説明します。

●メソッドのシグネチャの一般的な意味

シグネチャとは日本語にすると「署名」などの意味ですが、一般的なプログラミング言語(特にオブジェクト指向言語)におけるシグネチャも正にそういう意味で、唯一無二であることを示すためのもの(=メソッドの署名)です。1つのメソッドは基本的に1つのシグネチャを持っています。このようにシグネチャを持つことで、それぞれのメソッドがコンパイラなどで明確に区別できるわけです。

このシグネチャには、一般的には、「メソッド名」「パラメータ数と順序、パラメータの型」「戻り値の型」が含まれると考えられています。なお当然ながら、JavaやC#などで文の終わりを示す「;」はシグネチャには含めません。

しかしここで注意が必要です。実際には、現在の大半のプログラミング言語(Java言語やC#/VB言語、C++言語など)では「戻り値の型(return type)」をシグネチャに含めないからです。

●C#/VB言語におけるメソッドのシグネチャの意味

特にC#/VB言語の場合、「戻り値の型」に関するシグネチャの事情は少し複雑です。C#/VB 言語は CLR(Common Language Runtime)の CTS(Common Type System)および CLS(Common Language Specification)というの共通言語仕様の上に設計されています。つまり「C#/VB 言語=CTS&CLS」ではありません。実は、CTS&CLSはさまざまな言語をサポートするために、より広範な機能を持っており、なんとシグネチャに「戻り値の型」を含めています。CTS&CLSが含めているのにC#/VB言語は含めていないわけですが、これはC#/VB言語の設計者が意図的に含めなかったわけです(恐らくその方が言語的に美しいと考えたからです)。

では、C#/VB言語で、「戻り値の型」がシグネチャに含まれていないことを証明しましょう。

次のコードは「戻り値の型」のみが異なる2つのSampleメソッドをC#/VB言語で記述したものです。これらコンパイルするとコンパイルするとエラーになってしまいます。

【C#】

int Sample(int arg)

{

  return arg;

}

string Sample(int arg)

{

  return arg.ToString;

}

// エラー内容:'Sample' と呼ばれるメンバを同じパラメータの型で既に定義しています。

【VB】

Function Sample(ByVal arg As Integer) As Integer

  Return arg

End Function

Function Sample(ByVal arg As Integer) As String

  Return arg.ToString

End Function

' エラー内容:「Public Function Sample(arg As Integer) As Integer」 と 「Public Function Sample(arg As Integer) As String」 では、戻り値の型のみが異なるため、お互いをオーバーロードすることはできません。

両方のエラー内容を見ると分かるように、「戻り値の型」のみが異なるメソッドが複数存在するために、エラーとなっています。エラーになるのは、これらのメソッドが同じシグネチャ(署名)を持っていると、コンパイラに見なされたからです。つまり上記2つのメソッドはまったく同じ、以下のシグネチャを持っています。

【C#】

Sample(int arg)

【VB】

Sample(ByVal arg As Integer)

つまりC#/VB言語の「メソッドのシグネチャ」という表現を使った場合は、上記のようにしか書けないのです。

次の表記のように「戻り値の型」を含めてメソッドの定義を書き表したい場合は、「メソッドの構文」という表現が妥当です。

【C#】

int Sample(int arg)

【VB】

Function Sample(ByVal arg As Integer) As Integer

ちなみに、シグネチャに「パラメータ数と順序、パラメータの型」が含まれているおかげで、「メソッド名」が同じで「パラメータ数と順序、パラメータの型」が異なる複数のオーバーロード メソッドが作成可能です。

【参考資料】

Wikipedia:Method signature

MSDN Forum:Return type as part of a method's signature