我只是在编写一个简单的C#接口,我在其中放置了一个属性而没有考虑太远。例如:
public interface IMyInterface
{
string Name { get; set; }
object[][] Data { get; set;
}
我意识到当应用于接口和抽象基类时,我对属性有点困惑。在普通类中,此语法将为它在幕后生成的隐藏字符串成员生成访问器和更改器。
接口不应该有数据成员。那么,这种语法在这种情况下会做些不同的事情吗?
抽象类怎么样?如果我在抽象基类和派生类中使用相同的语法,那么最终都会有一个隐藏的成员吗?
答案 0 :(得分:2)
接口不应该有数据成员。
接口仅包含方法,属性,事件或索引器的签名。
另见c# properties on Interface。 至于你的第二个问题:
如果我在抽象基类和派生类中使用相同的语法,最终是否会有一个隐藏的成员?
是。您可以通过在基类上标记属性virtual
并在派生类上标记override
来阻止这种情况。
答案 1 :(得分:2)
接口不应该有数据成员。那么,这种语法在这种情况下会做些不同的事情吗?
技术上它不是数据成员 - 它是一个具有底层数据成员的get / set方法对。没有实施。
抽象类怎么样?如果我在抽象基类和派生类中使用相同的语法,那么最终都会有一个隐藏的成员吗?
如果类是抽象的,属性是virtual
,那么是,您将使用另一个自动实现的属性覆盖自动实现的属性(这是没有意义的)。
如果类是抽象的并且属性不是virtual
那么你仍然有两个实现,但是基类是隐藏父实现而不是覆盖它(如果它们都是自动实现的,那仍然没有意义)。
如果属性是抽象的,那么抽象类将不会具有实现。您将 在您的具体类中实现get / set(可以自动实现的机器人 )
答案 2 :(得分:1)
界面中的属性声明与实现完全分开。因此,您可以使用自动属性
实现它 private class MyImpl : IMyInterface
{
public string Name { get; set; }
public object[][] Data { get; set; }
}
或声明您自己的支持字段
private class MyImplBacked : IMyInterface
{
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
public object[][] Data { get; set; }
}
抽象类中的相同场景
public abstract class MyAbstractClass
{
public abstract string Name { get; set; }
public abstract object[][] Data { get; set; }
}
private class MyImpl : MyAbstractClass
{
public override string Name { get; set; }
public override object[][] Data { get; set; }
}
private class MyImplBacked : MyAbstractClass
{
private string _name;
public override string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
public override object[][] Data { get; set; }
}