编译器说我没有实现我的界面,但我是?

时间:2011-06-14 19:54:20

标签: c# .net inheritance interface

好的,我有两个名称空间。一个包含我的界面,一个包含实现类。像这样:

namespace Project.DataAccess.Interfaces
{
    public interface IAccount
    {
        string SomeMethod();
    }
}

namespace Project.DataAccess.Concrete
{
    class Account : Project.DataAccess.Interfaces.IAccount
    {
        string SomeMethod()
        {
            return "Test";
        }
    }
}

使用此代码我收到错误:

  

'Project.DataAccess.Concrete.Account'未实现接口成员'Project.DataAccess.Interfaces.IAccount.SomeMethod'。 'Project.DataAccess.Concrete.Account.SomeMethod'无法实现接口成员,因为它不是公共的

如果我将类和方法公开,它可以正常工作。但是,如果我改为使用接口名称限定方法名称,那么它也会修复它。为什么?例如:

namespace Project.DataAccess.Concrete
{
    class Account : Project.DataAccess.Interfaces.IAccount
    {
        string IAccount.SomeMethod()
        {
            return "Test";
        }
    }
}

为什么要修复它?如果我不这样做,为什么必须公开?

要清楚

我很清楚将其公开修复它。使方法签名看起来像这样没有公开修改它:

string IAccount.SomeMethod()

为什么?

7 个答案:

答案 0 :(得分:24)

接口实现需要公开或明确:

公开:

class Account : IAccount
{
    public string SomeMethod()
    {
        return "Test";
    }
}

显式:

class Account : IAccount
{
    string IAccount.SomeMethod()
    {
        return "Test";
    }
}

如果您未指定访问修饰符,则C#中的默认访问修饰符为private

答案 1 :(得分:3)

实现接口时有2个基本选项:隐式或显式。隐式实现采用公共方法或属性的形式,而显式采用以IFoo.修饰符开头的方法或属性的形式,否则不公开。

interface IFoo
{
    void Bar();
}

class FooA : IFoo
{
    public void Bar() { }
}

class FooB : IFoo
{
    void IFoo.Bar() { }
}

这里的区别在于,FooA的情况下,void Bar是该类公开可见API的一部分。代码可以通过类的实例调用Bar

FooA foo = new FooA(); 
foo.Bar(); // legal

对于FooBvoid Bar 是该类公开可见API的一部分。仍然可以调用该方法,但必须通过接口明确调用该方法。

FooB foo = new FooB();
foo.Bar(); // not legal
IFoo myFoo = foo;
myFoo.Bar(); // legal

您的代码无法编译,因为它介于隐式和显式接口实现之间的未知范围内。您看到通过您的更改,您已合法地定义了一个显式实现,这就是特定版本编译的原因。否则,您还发现需要public修饰符才能使非显式版本编译。

答案 2 :(得分:1)

实现接口的方法需要公开。在以后的情况下,您将明确声明它。这是关于显式接口实现的specification says

  

显式接口成员   实现有不同   可访问性特征比   其他成员。因为明确   接口成员实现是   从来没有完全可以访问   方法调用中的限定名称   或财产访问,他们在一个   感觉私密。但是,因为他们可以   通过界面访问   例如,它们在某种意义上也是如此   公共

答案 3 :(得分:1)

'Project.DataAccess.Concrete.Account.SomeMethod'无法实现接口成员,因为它不公开

namespace Project.DataAccess.Concrete
{
    public class Account : IAccount    
    {
        public string IAccount.SomeMethod()
        {
            return "Test";
        }
    }
}

答案 4 :(得分:1)

您在课堂宣言中没有提及您将实施IAccount

您的班级声明应如下所示:

class Account : IAccount
{ 
  //Implementation here.
}

此外,正在发生的事情是您使用Account的“默认”保护级别,并且该保护级别不是“公共”,但接口(IAccount)定义了公共方法默认情况下。

因此,当您使用public作为类和方法名称的前言时,您实际上正在实现该接口。同样,当您将SomeMethod声明为

IAccount.SomeMethod()
{
   //Implementation Here
}

你正在做的是明确地实现界面。

答案 5 :(得分:1)

我认为使用string IAccount.SomeMethod()明确声明它是有效的,因为.NET知道该方法的这种实现只能通过接口访问,因此它从接口继承了公共可见性。换句话说,因为你明确地说它是一个接口成员,编译器可能暗示它必须是公共的,所以你不必重新陈述显而易见的。

这也在这里讨论:http://msdn.microsoft.com/en-us/library/aa664591%28v=vs.71%29.aspx

  

这是一个编译时错误   显式接口成员   实现包括访问   修饰符,它是一个编译时   包含修饰符的错误   抽象,虚拟,覆盖或   静态的。

     

显式接口成员   实现有不同   可访问性特征比   其他成员。因为明确   接口成员实现是   从来没有完全可以访问   方法调用中的限定名称   或财产访问,他们在一个   感觉私密。但是,因为他们可以   通过界面访问   例如,它们在某种意义上也是如此   公共

答案 6 :(得分:0)

class Account : IAccount    
    {         
    public string SomeMethod()         
    {            
     return "Test";         
    }     
    } 

告诉您的班级实施该界面。使用Interface.Method名称显式实现该方法(但我不知道为什么或如何),并且您需要将它们公开。

当类已经拥有相同名称的成员时,您希望使用Interface.Method显式实现接口要求

class MyClass : IAccount
{
   public int SomeMethod() {}
   public string IAccount.SomeMethod() {}
}