您可以使用C#new关键字来扩展接口的属性吗?

我理解“new”关键字如何隐藏派生类中的方法。 但是,它对实现使用关键字的接口的类有什么影响?

考虑这个例子,我决定通过使其属性读/写来扩展接口。

public interface IReadOnly { string Id { get; } } public interface ICanReadAndWrite : IReadOnly { new string Id { get; set; } } 

然后你就可以做到这样的事情:

 public IReadOnly SomeMethod() { // return an instance of ICanReadAndWrite } 

这是不好的设计吗? 它会导致我的类实现ICanReadAndWrite的问题吗?

编辑:这是一个人为的例子, 说明为什么我可能想要做这样的事情:

假设我有一个返回IShoppingCartItemReadWrite的工厂类。 然后,我可以有一个服务层来操纵价格,更改东西等。然后,我可以将这些对象作为IShoppingCartItemReadOnly传递给某种不会改变它们的表示层。 (是的,我知道它在技术上可以改变它们 – 这是一个设计问题,而不是安全性等)

这不是一个特别糟糕的主意。 您应该知道实现者可以 (如果它隐式实现接口,那么单个读/写属性可以满足两个接口)提供两个不同的实现:

 class Test : ICanReadAndWrite { public string Id { get { return "100"; } set { } } string IReadOnly.Id { get { return "10"; } } } Test t = new Test(); Console.WriteLine(t.Id); // prints 100 Console.WriteLine(((IReadOnly)t).Id); // prints 10 

顺便说一下,一般来说, newinheritance修饰符除了告诉编译器关闭并且不抛出“你正在隐藏该成员”警告之外什么都不做。 省略它将对编译的代码没有影响。

您不应该基于IReadOnly实现ICanReadWrite,而是将它们分开。

即。 像这样:

 public interface IReadOnly { string Id { get; } } public interface ICanReadAndWrite { string Id { get; set; } } 

这是一个使用它们的类:

 public class SomeObject : IReadOnly, ICanReadWrite { public string Id { get; set; } } 

请注意,类中的相同属性可以支持这两个接口。

请注意,根据注释,获得强大解决方案的唯一方法是使用包装器对象。

换句话说,这不好:

 public class SomeObject : IReadOnly, ICanReadWrite { public string Id { get; set; } public IReadOnly AsReadOnly() { return this; } } 

因为调用者可以这样做:

 ICanReadWrite rw = obj.AsReadOnly() as ICanReadWrite; rw.Id = "123"; 

要获得强大的解决方案,您需要一个包装器对象,如下所示:

 public class SomeObject : IReadOnly, ICanReadWrite { public string Id { get; set; } public IReadOnly AsReadOnly() { return new ReadOnly(this); } } public class ReadOnly : IReadOnly { private IReadOnly _WrappedObject; public ReadOnly(IReadOnly wrappedObject) { _WrappedObject = wrappedObject; } public string Id { get { return _WrappedObject.Id; } } } 

这将工作,并且健壮,直到调用者使用reflection的点。

这是完全合法的,实现ICanReadAndWrite接口的类的含义只是当它被视为IReadOnly时它只能读取,但当被视为ICanReadAndWrite时,它将能够做到这两点。

我不确定是否编译,但不是一个可行的模式。 由于能够进行显式接口实现,理论上可以为Id属性的IReadOnlyICanReadAndWrite版本提供两种完全不同的实现。 考虑通过为属性添加setter方法而不是替换属性来更改ICanReadAndWrite接口。

你可以做到,但我不确定你希望通过这样做完成什么。

 public IReadOnly SomeMethod() { // return an instance of ICanReadAndWrite } 

此方法将返回对IReadOnly的引用,这意味着您返回ICanReadAndWrite并不重要。 这种做法不会更好吗?

 public interface IReadOnly { String GetId(); } public interface ICanReadAndWrite : IReadOnly { String SetId(); }