考虑以下界面
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
{
}
答案 0 :(得分:3)
接口不在那里提供实现,它是定义合同的。然后,这允许构建实现它的不同实现。
答案 1 :(得分:2)
它们在语法上可能完全相同,但它们意味着不同的东西(即它们不在语义上相同)。
在接口中,语法意味着实现类必须公开这样的属性,并在其认为合适时(显式或隐式)实现get
和set
访问器。界面只定义了类必须提供的外向行为;它没有提供该行为的任何实现。
在类中,语法是“auto-property”,接口定义的属性的实现,get
和set
访问器是隐式的转换为具有支持字段的完整实现。它在编译时看起来像这样:
public class CustomDataHandler : ICustomData
{
private string customData;
public string CustomData
{
get
{
return customData;
}
set
{
customData = value;
}
}
}
答案 2 :(得分:1)
您正在隐式实现该接口。在这种情况下,类的方法签名必须与接口的签名(包括可访问性)匹配。确保方法被标记为公共可确保在查看类时没有意外,例如:
public class CustomDataHandler : ICustomData
{
String CustomData {get; set}
String PrivateCustomData {get;set;}
}
即使两个属性都声明相同,CustomData属性也会因为它在接口上声明而公开,即使声明看起来与PrivateCustomData相同。这将是不一致的,并导致更难维护代码。
如果您不想设置访问修饰符,可以显式实现界面:
public class CustomDataHandler : ICustomData
{
String ICustomData.CustomData { set; get; }
}
答案 3 :(得分:0)
接口声明仅指定接口定义的行为。在您的情况下,这是一个名为CustomData
的属性,它具有get
和set
(它是读/写属性),类型为string
。
实现接口的类需要完全按照指定实现。
现在,在您的情况下,您使用的是自动实现的属性{ get; set; }
,它看起来与接口声明相同,但您也可以在get或set方法中使用支持字段和行为。
答案 4 :(得分:0)
您必须明确地实现它,因为......您不仅限于以这种方式实现它。您可以使用字段,或在方法中执行其他操作。接口只是保证此方法存在的方法契约。
public class CustomDataHandler : ICustomData
{
public String CustomData
{
get { return "None of your business!"; }
set { } // Decide to do nothing
}
}
界面只保证这种方法会存在。不是你要用它做什么。
编辑:至于您对问题的编辑,如果您只想为类集合实现一次该方法,则可能会尝试使用父类而不是接口。但是,虽然您可以组合界面,但您无法组合父类。但是,您可以在类层次结构的不同位置添加接口。
答案 5 :(得分:0)
以下是派生类中CustomData
属性为private
的示例:
public class CustomDataHandler : ICustomData
{
private string CustomData { set; get; }
string ICustomData.CustomData { get; set; }
}
但是这段代码编译,因为还有一个显式的属性实现。
因此,public
修饰符在这种情况下不是多余的。