CS0~400

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

CS0058 は C# のコンパイラ エラーで、宣言したデリゲートの戻り値の型のアクセシビリティが、デリゲート自体のアクセシビリティより低い場合に発生します。

たとえば、public なデリゲートが、非公開のクラスを戻す場合にエラーが表示されます。

アクセス修飾子を見直すことで解決できます。

エラー発生の原因

デリゲートとアクセス修飾子の基本

戻り値の型とアクセスレベルの不整合

C#では、デリゲートが返す戻り値の型のアクセスレベルが、デリゲート自体のアクセスレベルよりも低い場合、コンパイラ エラー CS0058が発生します。

たとえば、public delegateで宣言されたデリゲートが返す型が明示的にpublicで宣言されていない場合、戻り値の型のアクセスレベルはデフォルトでinternalprivateとなるため、エラーとなります。

このエラーは、型のアクセシビリティの不整合が原因です。

戻り値の型が参照できない状態になってしまうために、プログラム全体のアクセスが一貫しなくなってしまうのです。

クラス宣言のアクセス指定不足による問題

クラス宣言でアクセス修飾子を明示しない場合、クラスは既定でinternalまたはprivateとして扱われます。

たとえば、以下のようなコードでは、MyClassのアクセス修飾子が指定されていないため、デフォルトのアクセスレベルとなります。

class MyClass
{
    // クラスの実装
}
public delegate MyClass MyClassDel();   // CS0058 エラーが発生

この状態では、publicなデリゲートが、アクセスが限定されたMyClassを返すため、アクセスレベルに不一致が生じ、エラーが発生します。

一般的な設定ミス

公開属性の不足ケース

一般的な設定ミスとして、クラスや戻り値の型にpublicの公開属性を付与し忘れることが挙げられます。

特に、複数のファイルに分割して開発を進めている場合、アクセス修飾子の指定漏れが発生しやすくなります。

この場合、意図せずにprivateinternalとなるため、デリゲートや他の公開APIとの間で不整合が生じ、コンパイル時にCS0058エラーが検出されます。

適切なアクセス修飾子の指定は、型の利用範囲を明示的に管理するために重要です。

エラー発生前に、対象のクラスや構造体に正しい公開属性が設定されているかどうか確認することが望ましいです。

エラー対処の具体的方法

アクセス修飾子の見直し

エラーを解決するためには、型の宣言やデリゲート定義に対して適切なアクセス修飾子を付与する必要があります。

以下の方法を参考に、アクセス修飾子を見直してください。

クラス宣言の修正例

クラスのアクセス修飾子を明示的にpublicに指定することで、デリゲートとのアクセスレベルの不一致を解消できます。

次のコードは、MyClasspublicを付加する例です。

using System;
public class MyClass   // クラスに public 修飾子を追加
{
    public string Message { get; set; } = "MyClass インスタンスです";
}
public delegate MyClass MyClassDel();  // publicデリゲートが publicなMyClassを返す例
public class Program
{
    public static void Main()
    {
        MyClassDel del = GetMyClassInstance;  // デリゲートにメソッドを割り当て
        MyClass instance = del();              // デリゲート呼び出し
        Console.WriteLine(instance.Message);   // 結果表示
    }
    public static MyClass GetMyClassInstance()
    {
        return new MyClass();
    }
}
MyClass インスタンスです

デリゲート定義の再設定

場合によっては、戻り値の型を変更することも対策のひとつです。

もし、型そのものを公開する必要がない場合は、デリゲートのアクセスレベルを型に合わせることでエラーを解消できます。

ただし、一般的には戻り値の型を公開するほうがAPI全体の整合性が取れるため、クラスや型のアクセス修飾子を変更する方法が推奨されます。

修正後のコンパイル検証

コード修正後の動作チェック

アクセス修飾子の修正を行った後、実際にコンパイルおよび実行し、意図した動作が確認できるかチェックする必要があります。

コンパイルエラーが発生しなくなった場合、修正内容が正しく適用されたと判断できます。

また、デリゲートを通じたメソッド呼び出しで正しい値が返されるか、実行時にConsole.WriteLine等で出力を確認してください。

以下は、修正後のコードを改めて確認するためのサンプル例です。

using System;
public class MyClass   // 正しく public に設定
{
    public string Message { get; set; } = "正常に動作しています";
}
public delegate MyClass MyClassDel();  // 修正済みのデリゲート定義
public class Program
{
    public static void Main()
    {
        // 修正後のデリゲートの動作確認
        MyClassDel delegateInstance = CreateMyClassInstance;
        MyClass instance = delegateInstance();
        Console.WriteLine(instance.Message);   // 実行結果を確認
    }
    public static MyClass CreateMyClassInstance()
    {
        return new MyClass();
    }
}
正常に動作しています

サンプルコードによる検証

エラー発生例の解説

問題点の詳細分析

ここではエラー発生例として、アクセス修飾子の指定漏れによってCS0058が発生するパターンを紹介します。

以下のサンプルでは、MyClassがアクセス修飾子を省略して宣言されているため、デリゲートMyClassDelの戻り値の型として使用できず、エラーが発生します。

using System;
// アクセス修飾子が指定されていないため、MyClassは既定で internal または private となる
class MyClass
{
    public string Message { get; set; } = "エラーが発生中";
}
// publicデリゲートがMyClassを返すため、アクセスレベルの不整合が発生
public delegate MyClass MyClassDel();
public class Program
{
    public static void Main()
    {
        MyClassDel delegateInstance = GetMyClassInstance;
        MyClass instance = delegateInstance();
        Console.WriteLine(instance.Message);
    }
    public static MyClass GetMyClassInstance()
    {
        return new MyClass();
    }
}

上記のコードでは、MyClassが公開されていないため、publicMyClassDelと整合性が取れず、コンパイル時にCS0058エラーが発生します。

修正後コード例の説明

変更箇所の具体的説明

エラーを解消するために、MyClasspublic修飾子を付与する必要があります。

次の例は、すべての型を正しいアクセスレベルで宣言することで、エラーを解消したものです。

using System;
public class MyClass   // public を追加して、デリゲートと整合性を確保
{
    public string Message { get; set; } = "修正済みのコードが正しく実行中";
}
public delegate MyClass MyClassDel();  // 引き続き public のデリゲートを使用
public class Program
{
    public static void Main()
    {
        // デリゲートを通じたインスタンスの生成を確認
        MyClassDel delegateInstance = CreateMyClassInstance;
        MyClass instance = delegateInstance();
        Console.WriteLine(instance.Message);  // 出力結果で動作を確認
    }
    public static MyClass CreateMyClassInstance()
    {
        return new MyClass();
    }
}
修正済みのコードが正しく実行中

このコード例では、MyClassの宣言にpublicを付けることで、コンパイラがCS0058エラーを出力しなくなったほか、デリゲートおよびMainメソッドから正しくアクセスできるようになりました。

まとめ

本記事では、C#のコンパイラ エラーCS0058が発生する原因とその対処法について解説しています。

デリゲートの戻り値として指定された型のアクセシビリティがデリゲート自体のものと一致しない場合に起こる問題に注目し、クラス宣言のアクセス修飾子の設定不足や一般的な設定ミスが原因となるケースを紹介しました。

サンプルコードを用いて、具体的な修正例や動作確認の方法を示すことで、正しいアクセス指定の方法が理解できる内容となっています。

関連記事

Back to top button