1

考虑以下接口

public interface ICustomData
{
    String CustomData { set; get; }
}

根据 MSDN 文档,接口成员是自动公开的。

假设我现在想实现我的接口:

public class CustomDataHandler : ICustomData
{
}

这会在编译时中断,告诉我我没有实现“CustomData”

另一方面,这将起作用:

public class CustomDataHandler : ICustomData
{
    public String CustomData { set; get; }
}

我的问题是:如果接口的成员自动公开,为什么我必须在类中声明实现?如果接口声明在语法上与类声明相同,为什么编译器不能从我的接口自动推断出来?

编辑:

我问的理由。想象一下您正在构建数据模型、实体等的场景。我可能会为这些模型编写一些接口,如下所示:

public interface IUserAccount
{
    Guid Identity { set; get; }
    String FirstName { set; get; }
    String LastName { set; get; }
    String EmailAddress { set; get; }
    String Password { set; get; }
}

public interface IUserDataEntry
{
    Guid DataIdentity { set; get; }
    String DataName { set; get; }
    String Data { set; get; }
}

像这样构建模型会简单得多:

public class UserAccount : IUserAccount
{
}

public class UserDataEntry : IUserDataEntry
{
}

public class Combined : IUserAccount, IUserDataEntry
{
}
4

6 回答 6

3

接口不是用来提供实现的,它是用来定义契约的。然后,这允许构建实现它的不同实现。

于 2012-11-06T09:07:50.523 回答
2

它们在句法上可能相同,但它们的含义不同(即它们在语义上并不相同)。

在接口中,语法意味着实现类必须公开这样的属性,getset按照它认为合适的方式实现访问器(显式或隐式)。接口仅仅定义了一个类必须提供的外在行为;它不提供该行为的任何实现。

在该类中,语法是“自动属性”,是接口定义的属性的实现,并且get访问set器被隐式转换为具有支持字段的完整实现。编译后看起来像这样:

public class CustomDataHandler : ICustomData
{
    private string customData;

    public string CustomData
    {
        get
        {
            return customData;
        }
        set
        {
            customData = value;
        }
    }
}
于 2012-11-06T09:08:04.687 回答
1

您正在隐式实现接口。在这种情况下,类的方法签名必须与接口的方法签名匹配(包括可访问性)。确保方法被标记为公共确保在查看类时不会出现意外,例如:

public class CustomDataHandler : ICustomData
{
  String CustomData {get; set}
  String PrivateCustomData {get;set;}
}

即使两个属性声明相同,CustomData 属性也将是公共的,因为它是在接口上声明的,即使声明看起来与 PrivateCustomData 的声明相同。这将是不一致的,并导致更难维护代码。

如果您不想设置访问修饰符,则可以显式实现该接口:

public class CustomDataHandler : ICustomData
{
    String ICustomData.CustomData { set; get; }
}
于 2012-11-06T09:06:40.573 回答
0

您必须明确地实现它,因为......您不仅限于以这种方式实现它。您可以使用一个字段,或者在您的方法中执行其他操作。接口只是保证该方法存在的方法契约。

public class CustomDataHandler : ICustomData
{
    public String CustomData
    {
        get { return "None of your business!"; }
        set { } // Decide to do nothing
    }
}

接口只保证这个方法会存在。不是你要用它做什么。

编辑:至于您对问题的编辑,如果您只想为一组类实现一次方法,您可能会寻求拥有一个父类而不是接口。但是,虽然可以组合接口,但不能组合父类。但是,您可以在类层次结构的不同点添加接口。

于 2012-11-06T09:09:11.440 回答
0

CustomData这是一个属性private位于派生类中的示例:

public class CustomDataHandler : ICustomData
{
    private string CustomData { set; get; }

    string ICustomData.CustomData { get; set; }
}

但是这段代码可以编译,因为还有一个显式的属性实现。

因此,public在这种情况下,修饰符不是多余的。

于 2012-11-06T09:10:47.210 回答
0

接口声明仅指定接口定义的行为。在您的情况下,这是一个名为的属性CustomData,它有一个getand set(它是一个读/写属性),它的类型是string

实现接口的类需要完全做到这一点——以指定实现

现在,在您的情况下,您使用的自动实现的属性{ get; set; }看起来与接口声明相同,但是您的 get 或 set 方法中也可以有一个支持字段和行为。

于 2012-11-06T09:08:06.543 回答