1. ホーム
  2. c#

コンパイルエラーです。「インターフェイスの明示的な実装中に「修飾子 'public' はこのアイテムでは有効ではありません。

2023-10-15 21:19:14

質問

を作成する際に、このエラーが発生します。 public メソッドを明示的に実装するために interface . を明示的に実装しているクラスを削除することで、回避することができます。 PrintName メソッドの明示的な実装を削除することです。しかし、私はなぜこのエラーが発生するのだろうかと驚いています。

どなたかこのエラーを説明していただけませんか?

ライブラリのコードです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Test.Lib1
{

    public class Customer : i1 
    {
        public string i1.PrintName() //Error Here...
        {
            return this.GetType().Name + " called from interface i1";
        }
    }

    public interface i1
    {
        string PrintName();
    }

    interface i2
    {
        string PrintName();
    }
}

コンソールテストアプリケーションのコードです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Test.Lib1;

namespace ca1.Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Customer customer = new Customer();
            Console.WriteLine(customer.PrintName());

            //i1 i1o = new Customer();
            //Console.WriteLine(i1o.printname());

            //i2 i2o = new Customer();
            //Console.WriteLine(i2o.printname());

        }
    }
}

どのように解決するのですか?

を使用する場合 明示的 の実装を使う場合、メンバは プライベート よりも制限されたものに強制されます。また、アクセス修飾子が強制される場合、追加することはできません。

同様に、インタフェース自身では、すべてのメンバが public . もし、インターフェイスの中にモディファイアを追加しようとすると、同様のエラーが発生します。

なぜ明示的なメンバは(非常に)プライベートなのか?考えてみてください。

interface I1 { void M(); }
interface I2 { void M(); }

class C : I1, I2
{
    void I1.M() { ... }
    void I2.M() { ... }
}

C c = new C();
c.M();         // Error, otherwise: which one?
(c as I1).M(); // Ok, no ambiguity. 

これらのメソッドがpublicであった場合、通常のオーバーロードのルールでは解決できない名前の衝突が発生します。

同じ理由で、あなたは M() の内部から class C のメンバーで構成されます。をキャストする必要があります。 this を特定のインターフェイスにキャストする必要があります。

class C : I1, I2
{
   ...
   void X() 
   {  
     M();             // error, which one? 
     ((I1)this).M();  // OK 
   }
}