当我搜索有关界面的相关主题时,我在MSDN网站上找到了这个:
例如,接口可能声明具有get访问器的属性。实现接口的类可以使用get和set访问器声明相同的属性。 from MSDN
现在我怀疑了。当我们特别提到该属性应该只读时(在接口中只有'get'访问者)为什么还允许实现'set'访问器呢?
答案 0 :(得分:12)
现在我怀疑了。当我们特别提到该属性应该只读时(在接口中只有'get'访问者)为什么还允许实现'set'访问器呢?
有一点不同 - 当您使用接口时,您不是“指定该属性应该只读”,而是指定合同定义该特定名称和类型的“可读属性”。基本上,界面定义了合同的最低要求,而不是绝对要求。
如果将对象强制转换为特定接口,则属性设置器将不可用。它与在对象上具有通过接口不可用的额外属性或方法没有什么不同。
答案 1 :(得分:3)
您无法从接口引用访问set
属性,因此在向公众显示接口时是否实现它并不重要。
当然有时需要在类侧实现set访问器,即在使用允许访问同一程序集中的类的类时。
答案 2 :(得分:3)
接口是最低要求,需要实施,但您可以实施更多。在这种情况下,读写属性不仅仅是只读属性。
除了超出合同要求之外,您还可以添加任何其他方法和/或属性,并在同一个类中实现其他接口。
答案 3 :(得分:2)
使用该接口的代码不知道有一个集合,因此无法使用它。
答案 4 :(得分:0)
将接口视为合同。实施者承诺至少遵守该合同中定义的行为,但不限于此。接口允许组件在不紧密耦合的情况下进行交互。因此,实施可能允许get
和set
,但至少必须尊重get
。
答案 5 :(得分:0)
该类满足接口的要求,其他任何东西都是类本身的实现细节。如果你通过界面引用对象,你只会看到get。所以,不,它并没有真正打破它,它是按照预期的。
答案 6 :(得分:0)
接口虽然只是消费者如何使用该对象的声明。它没有对实现做出任何规范。那里没有矛盾。
答案 7 :(得分:0)
public interface IFoo {
string Name { get; }
}
class FooImplementation : IFoo {
public string Name { get; set; }
}
public class FooWorker {
public void WorkOnFoo(IFoo foo) {
if (null == foo) throw new ArgumentNullException("foo");
Console.WriteLine(foo.Name);
}
}
public class Program {
public void Main() {
IFoo foo = new FooImplementation { Name = "Foo" };
new FooWorker().WorkOnFoo(foo);
}
}
就FooWorker
而言,foo
参数只有get
属性的Name
访问者。
重要的是要记住Name
属性仍然可以通过反射或演员在foo
上设置。
答案 8 :(得分:0)
菲利克斯说的是正确的。
更详细地说,接口定义了最小功能集,这些功能必须存在于定义为实现所述接口的任何对象上。这在接口的所有实现中提供了“通用”功能集,因此您知道如果对象实现了接口,您可以在其上调用X,Y和Z.例如,因为某些东西是IDisposable,并不意味着所有对象都能做到。实际上,如果接口定义了最大量的功能,那么接口将变得毫无意义。当你使用对象作为接口的实现时,这就是你所关心的所有事情;如果您只需要一个IDisposable,那么您只关心调用Dispose(),而不管特定IDisposable实现可能具有哪些其他成员。
回到您的示例,定义属性的接口声明必须具有公共get访问器。它不会,也不能说它不能拥有公共集访问器;它根本不关心任何一种方式。 set访问器可以是public,internal,protected,private或不存在;接口的消费者期望什么,以及接口的实现者需要什么,是get访问器。
答案 9 :(得分:0)
根据三种类型的事物进行思考可能会有所帮助:抽象的ReadableFoo
类(或IReadableFoo
接口),以及具体的ImmutableFoo
和MutableFoo
类(或IImmutableFoo
和IChangeableFoo
接口)。接收类型ReadableFoo
的参数的人将能够读取它,但无法设置它,并且仅通过持久引用将无法可靠地持久保存其中的数据。接收参数ImmutableFoo
的人将能够通过持久引用来可靠地保留数据,但无法更改它。收到参数MutableFoo
的人将能够更改数据,但不能通过持久引用来可靠地保留数据。