CS801~2000

C# コンパイラエラー CS1936 の原因と対策について解説

C#のコンパイラエラーCS1936は、クエリ演算子を使用する際に、対象の型に必要なクエリメソッドが実装されていない場合に発生します。

個々のオブジェクトに対してクエリが実行されると起こることが多く、オブジェクトのコレクションを適切にクエリし、必要なusingディレクティブが取り込まれているか確認してください。

エラー発生の背景

CS1936エラーの概要

CS1936エラーは、LINQのクエリ式やメソッドチェーンにおいて、対象の型が標準のクエリ演算子を実装していない場合に発生するエラーです。

つまり、クエリとして扱おうとした型に対して、必要な拡張メソッド(例:WhereSelectなど)が定義されていない場合に表示されます。

また、適切なusingディレクティブが指定されていない場合もこのエラーが表示される可能性があります。

エラーが発生する具体的な状況

エラーが発生する代表的な状況は、次のような場合です。

  • オブジェクトそのものに対してLINQのクエリ演算子を適用しようとした場合
  • 対象の型が標準クエリ演算子を実装していない場合
  • 必要なusingディレクティブ(主にusing System.Linq;)がファイルの先頭に記載されていない場合

これらの状況では、LINQのクエリ構文が正しく解釈されず、コンパイラは該当するクエリパターンの実装を見つけることができずにCS1936エラーを返します。

原因の詳細

クエリパターンに必要なメソッドの未実装

LINQクエリを正しく使用するためには、クエリ対象の型が標準クエリ演算子、例えばSelectWhereOrderByなどのメソッドを実装している必要があります。

これらのメソッドは、通常拡張メソッドとして定義されており、適切なusingディレクティブがあることで利用可能になります。

もし、クエリを実行しようとしているオブジェクトがこれらのメソッドを持たない場合、コンパイラは実装が見つからずにCS1936エラーを出力します。

usingディレクティブの不足による影響

LINQのクエリ演算子は、主にSystem.Linq名前空間に定義されています。

ソースコード内でこの名前空間をインポートしていないと、拡張メソッドがスコープに取り込まれず、正しくクエリが実行されません。

その結果、必要なメソッドが存在しているにもかかわらず、コンパイラがそのメソッドを見つけられずにエラーを発生させることがあります。

対策方法

対象オブジェクトの型確認

まず、LINQクエリを実行する対象が正しくコレクション型であるか確認してください。

単一のオブジェクトに対してクエリを実行しようとすると、標準のクエリ演算子が存在しないためCS1936エラーが発生します。

例えば、object型の変数に対してクエリを実行している場合は、実際にクエリを実行したいコレクション型(IEnumerable<T>List<T>など)に変更する必要があります。

必要なusingディレクティブの追加

コード内にusing System.Linq;が記載されているかを確認してください。

LINQのクエリ演算子はこの名前空間内で定義されているため、これが不足しているとコンパイラは拡張メソッドを認識できません。

必ずファイルの先頭に以下のように記載し、名前空間をインポートしてください。

using System.Linq;

コード例による検証

問題が発生するコード例

リファクタリング前の状態

以下のサンプルコードは、単一のオブジェクトに対してLINQクエリを実行しようとしているため、CS1936エラーが発生する例です。

// SampleBefore.cs
using System.Collections;
using System.Linq; // usingディレクティブは指定済みだが、対象が正しい型ではない
class Program
{
    static int Main()
    {
        object obj = "サンプル文字列"; // 単一のオブジェクト
        // LINQクエリを実行しようとするとエラーが発生する
        IEnumerable query = from x in obj
                            select x;
        return 0;
    }
}
コンパイラ エラー CS1936: ソース型 'object' のクエリ パターンの実装が見つかりませんでした。 'Select' が見つかりません

修正後のコード例

適切なクエリパターンの実装例

以下のサンプルコードは、対象の型をコレクションに変更し、また必要なusingディレクティブを正しく記載することで、エラーを回避しています。

コード内のコメントでポイントを説明しています。

// SampleAfter.cs
using System;
using System.Collections.Generic; // List<T>を利用するために必要
using System.Linq;  // LINQのクエリ演算子を使用するために必要
class Program
{
    static int Main()
    {
        // コレクション型のリストを作成
        List<string> stringList = new List<string>()
        {
            "リンゴ", "バナナ", "オレンジ"
        };
        // LINQクエリを使用して、"an"を含む文字列を抽出する
        var query = from fruit in stringList
                    where fruit.Contains("an")
                    select fruit;
        // 結果を出力する
        foreach (var item in query)
        {
            Console.WriteLine(item);
        }
        return 0;
    }
}
バナナ

まとめ

本記事では、CS1936エラーの概要と発生する具体的な状況、及び原因について解説しています。

対象の型が正しくコレクションでない場合や、必要なusingディレクティブが不足している場合にエラーが発生するため、型の確認とusingディレクティブの追加が必要である点が分かりました。

具体的なコード例を通して、エラー発生前後のリファクタリングの手順も理解できます。

関連記事

Back to top button