是不是破坏了c#界面的设计原则?

时间:2012-02-23 17:33:34

标签: c# interface

当我搜索有关界面的相关主题时,我在MSDN网站上找到了这个:

  

例如,接口可能声明具有get访问器的属性。实现接口的类可以使用get和set访问器声明相同的属性。   from MSDN

现在我怀疑了。当我们特别提到该属性应该只读时(在接口中只有'get'访问者)为什么还允许实现'set'访问器呢?

10 个答案:

答案 0 :(得分:12)

  

现在我怀疑了。当我们特别提到该属性应该只读时(在接口中只有'get'访问者)为什么还允许实现'set'访问器呢?

有一点不同 - 当您使用接口时,您不是“指定该属性应该只读”,而是指定合同定义该特定名称和类型的“可读属性”。基本上,界面定义了合同的最低要求,而不是绝对要求。

如果将对象强制转换为特定接口,则属性设置器将不可用。它与在对象上具有通过接口不可用的额外属性或方法没有什么不同。

答案 1 :(得分:3)

您无法从接口引用访问set属性,因此在向公众显示接口时是否实现它并不重要。

当然有时需要在类侧实现set访问器,即在使用允许访问同一程序集中的类的类时。

答案 2 :(得分:3)

接口是最低要求,需要实施,但您可以实施更多。在这种情况下,读写属性不仅仅是只读属性。

除了超出合同要求之外,您还可以添加任何其他方法和/或属性,并在同一个类中实现其他接口。

答案 3 :(得分:2)

使用该接口的代码不知道有一个集合,因此无法使用它。

答案 4 :(得分:0)

将接口视为合同。实施者承诺至少遵守该合同中定义的行为,但不限于此。接口允许组件在不紧密耦合的情况下进行交互。因此,实施可能允许getset,但至少必须尊重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接口),以及具体的ImmutableFooMutableFoo类(或IImmutableFooIChangeableFoo接口)。接收类型ReadableFoo的参数的人将能够读取它,但无法设置它,并且仅通过持久引用将无法可靠地持久保存其中的数据。接收参数ImmutableFoo的人将能够通过持久引用来可靠地保留数据,但无法更改它。收到参数MutableFoo的人将能够更改数据,但不能通过持久引用来可靠地保留数据。