C# 编译器说我并没有实现我的接口,但我实现了?

C# 编译器说我并没有实现我的接口,但我实现了?,c#,.net,inheritance,interface,C#,.net,Inheritance,Interface,好的,我有两个名称空间。一个包含我的接口,另一个包含实现类。像这样: namespace Project.DataAccess.Interfaces { public interface IAccount { string SomeMethod(); } } namespace Project.DataAccess.Concrete { class Account : Project.DataAccess.Interfaces.IAccount

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

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()

为什么?

实现接口的方法需要是公共的。在后面的例子中,您将显式地声明它。这就是显式接口实现

显式接口成员 实现有不同的功能 可访问性特征比 其他成员。因为明确 接口成员实现是 永远无法通过他们的 方法调用中的限定名 或一个属性访问,它们位于 感觉隐私。但是,既然可以, 可以通过接口访问 例如,它们在某种意义上也是 公众

告诉您的类实现接口。使用Interface.Method name显式实现该方法(但我不确定为什么或如何实现),您需要将它们公开

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

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

“Project.DataAccess.Concrete.Account.SomeMethod”无法实现接口成员,因为它不是公共的

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

接口实现需要是公共的或显式的:

公众:

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

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

如果不指定访问修饰符,C#中的默认访问修饰符是
private

在类声明中没有提到要实现
IAccount

您的类声明应该如下所示:

class Account : IAccount
{ 
  //Implementation here.
}
另外,您正在使用
帐户
的“默认”保护级别,并且该保护级别不是“公共”的,而是一个接口(
IAccount
)默认定义了公共方法

因此,当您用
public
为类和方法名添加前缀时,实际上是在实现接口。同样,当您将
SomeMethod
声明为

IAccount.SomeMethod()
{
   //Implementation Here
}

您所做的是显式实现接口。

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

interface IFoo
{
    void Bar();
}

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

class FooB : IFoo
{
    void IFoo.Bar() { }
}
FooB foo = new FooB();
foo.Bar(); // not legal
IFoo myFoo = foo;
myFoo.Bar(); // legal
这里的区别在于,在
FooA
的情况下,
void Bar
是类的公共可见API的一部分。代码可以通过类的实例调用Bar

FooA foo = new FooA(); 
foo.Bar(); // legal
FooB
的情况下,
void Bar
不是类的公共可见API的一部分。仍然可以调用该方法,但必须通过接口显式调用它

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

您的代码不会编译,因为它在隐式和显式接口实现之间的未知水域中行走。您看到,通过更改,您已经合法地定义了显式实现,这就是为什么要编译特定版本。否则,您还发现需要使用
public
修改器来编译非显式版本。

我认为使用
字符串IAccount.SomeMethod()
显式声明它是有效的,因为.NET知道该方法的此实现只能通过接口访问,因此,它从界面上传递了公众的可见性。换句话说,因为您明确地说它是接口成员,编译器可以暗示它必须是公共的,所以您不必重新声明显而易见的

这里也讨论了这一点:

这是一个编译时错误 显式接口成员 实施包括访问 修饰符,这是一个编译时 包含修改器时出错 抽象、虚拟、重写或 静态的

显式接口成员 实现有不同的功能 可访问性特征比 其他成员。因为明确 接口成员实现是 永远无法通过他们的 方法调用中的限定名 或一个属性访问,它们位于 感觉隐私。但是,既然可以, 可以通过接口访问 例如,它们在某种意义上也是 公众


正如我特别指出的那样。公开可以修复它,但是为什么指定
IAccount.SomeMethod
而不公开也可以修复它呢?大概是因为接口成员必须是公开的,所以当它显式声明时,编译器足够聪明,可以将它公开,但是如果您不显式地将它绑定到IAccount,编译器不确定您是否指的是其他“SomeMethod()”,有趣的是,您不能为显式实现的接口指定任何访问修饰符。我很想看到为这些生成的IL。我的意思是,它可以被外部类调用,但前提是首先将它转换到该接口。这其实很奇怪这真的很有用。我有划分应用程序层的接口,我永远不希望在没有接口的情况下使用它们。显式实现接口正是我需要做的:)可能的重复