C#拡張メソッド定義におけるコンパイラエラー CS1106 について解説
CS1106エラーは、C#で拡張メソッドを定義する際に、非ジェネリックの静的クラスで記述されなかった場合に発生します。
拡張メソッドは静的メソッドとして設定し、定義するクラス自体も静的かつ非ジェネリックである必要があります。
コードを正しく修正することで解決できます。
エラーメッセージの解説
拡張メソッドの定義条件
静的クラスである必要性
拡張メソッドは、コンパイラが対象となる型に対してメソッドを呼び出す際に、自動的に解決する仕組みを採用しています。
そのため、拡張メソッドは明確に区別される存在でなければならず、通常のインスタンスメソッドと混同しないようにする必要があります。
C#では、この仕組みを保証するために、拡張メソッドは必ず静的クラス内に定義する必要があります。
静的クラスであることにより、インスタンスの生成を防ぎ、メソッドが単一の実装として扱われるため、拡張メソッドとして正しく機能します。
非ジェネリックでなければならない理由
拡張メソッドは、呼び出し時にシンプルな構文で利用できることが求められます。
もしクラス自体がジェネリックである場合、型パラメータの指定が必要となり、拡張メソッドとしての利便性が損なわれます。
さらに、ジェネリッククラスの場合、型推論や呼び出し側での扱いに複雑さが増すため、C#の言語仕様として拡張メソッドは非ジェネリックな静的クラスで定義するよう決められています。
発生するエラーケース
非静的クラスでの定義例
非静的なクラス内に拡張メソッドを定義すると、コンパイラは拡張メソッドとして認識できず、CS1106エラーが発生します。
下記のコード例は、非静的なクラスで拡張メソッドを定義した場合の典型例です。
// エラーが発生するコード例(非静的クラス内で拡張メソッドを定義)
// コンパイラ エラー CS1106: 拡張メソッドは非ジェネリックの静的クラスで定義する必要があります。
public class NonStaticClass
{
public static void ExtensionMethod(this int num) // CS1106エラー
{
// 拡張メソッド処理(例:何もしない)
}
}
class Program
{
static void Main(string[] args)
{
// このコードはコンパイルすら通りません
}
}
静的ジェネリッククラスでの定義例
拡張メソッドは静的クラスで定義する必要がありますが、もし静的クラスがジェネリッククラスである場合もCS1106エラーが発生します。
ジェネリックパラメータが存在すると、拡張メソッドとして正しく解釈されないためです。
以下のコード例では、静的ジェネリッククラス内で拡張メソッドを定義した場合のエラー例を示します。
// エラーが発生するコード例(ジェネリック静的クラス内で拡張メソッドを定義)
// コンパイラ エラー CS1106: 拡張メソッドは非ジェネリックの静的クラスで定義する必要があります。
public static class StaticGenericClass<T>
{
public static void ExtensionMethod(this int num) // CS1106エラー
{
// 拡張メソッド処理(例:何もしない)
}
}
class Program
{
static void Main(string[] args)
{
// このコードはコンパイルすら通りません
}
}
正しい拡張メソッド定義の方法
必要なクラス仕様
静的かつ非ジェネリックな定義の要点
正しく拡張メソッドを定義するためには、以下の点に注意する必要があります。
・拡張メソッドは必ず静的なクラスに定義する
・そのクラスはジェネリックであってはならない
・拡張メソッド自体も静的メソッドとして定義する
・第一引数には対象型に対してthis
キーワードを付ける
上記の要件を満たすことで、コンパイラは拡張メソッドとして正しく認識し、利用側でもシンプルな構文で呼び出すことが可能になります。
正しいコード実装例
コードサンプルの解説
以下のサンプルコードは、拡張メソッドを正しく定義した例です。
クラス名はExtensionMethods
という静的かつ非ジェネリックなクラス内に、整数型を拡張するメソッドAddValue
を定義しています。
this int number
により、整数型に対して拡張メソッドが適用されるようになっています。
Main
関数内で、整数変数に対して拡張メソッドがどのように呼び出され、結果が表示されるか確認できます。
using System;
namespace ExtensionExample
{
// 静的かつ非ジェネリックなクラス内に拡張メソッドを定義
public static class ExtensionMethods
{
// int型の値に指定した値を加える拡張メソッド
public static int AddValue(this int number, int value)
{
return number + value;
}
}
class Program
{
static void Main(string[] args)
{
int sample = 10;
// 拡張メソッドの呼び出し
int result = sample.AddValue(5);
Console.WriteLine("結果: " + result);
}
}
}
結果: 15
エラー解消のポイント
エラーを解消するためには、拡張メソッドの定義場所として以下の点を確認してください。
・非静的なクラスやジェネリックな静的クラスで定義していないか?
・拡張メソッドの第一引数にthis
キーワードが正しく付与されているか?
これらを確認して静的かつ非ジェネリックなクラス内に実装することで、CS1106エラーを回避できます。
修正例の比較検証
エラー発生前のコード例
下記のコードは、エラーが発生する状態を示しています。
非静的クラスおよびジェネリックな静的クラス内に拡張メソッドを定義しているため、どちらもコンパイル時にCS1106エラーが発生します。
using System;
namespace ErrorExtensionExample
{
// 非静的クラスで定義した拡張メソッド(コンパイルエラー CS1106)
public class NonStaticExtension
{
public static void WrongExtension(this int number) // CS1106エラー
{
// 何もしない処理
}
}
// 静的ジェネリッククラスで定義した拡張メソッド(コンパイルエラー CS1106)
public static class GenericExtension<T>
{
public static void WrongExtension(this int number) // CS1106エラー
{
// 何もしない処理
}
}
class Program
{
static void Main(string[] args)
{
// エラー例のため、実行するコードはありません
}
}
}
エラー解消後のコード例
下記は、上記エラーを解消した正しい実装例です。
拡張メソッドは静的かつ非ジェネリックなクラスExtensionMethods
内に定義され、正常に実行できます。
using System;
namespace ExtensionExample
{
// 正しく定義された静的かつ非ジェネリックなクラス
public static class ExtensionMethods
{
// int型に対して値を加える拡張メソッド
public static int AddValue(this int number, int value)
{
return number + value;
}
}
class Program
{
static void Main(string[] args)
{
int sample = 10;
// 拡張メソッドの呼び出し
int result = sample.AddValue(5);
Console.WriteLine("結果: " + result);
}
}
}
結果: 15
まとめ
記事では、拡張メソッドの正しい定義方法として、静的かつ非ジェネリックなクラス内で定義する必要性を具体例とともに解説しています。
非静的クラスやジェネリック静的クラスでの定義によるCS1106エラーの発生原因と、正しい実装方法を具体的なコード例を交えて説明しており、エラー解消のポイントを理解することができます。