C#:接口继承getters / setters

时间:2009-11-24 16:49:37

标签: c# design-patterns inheritance interface

我有一组接口,它们与特定的可变对象紧密结合使用。

该对象的许多用户只需要能够从对象读取值,然后只需要几个属性。为了避免命名空间污染(更容易智能感知)和跨越使用意图,我希望有一个小的基本接口,它只以只读方式公开一些“关键”属性。

但是,几乎所有实现都支持完整的界面,包括可修改性。

不幸的是,我遇到了在C#中表达这个概念的障碍:

interface IBasicProps {
   public int Priority { get; }
   public string Name {get;}
   //... whatever
}

interface IBasicPropsWriteable:IBasicProps  {
   public int Priority { set; } //warning CS0108: [...] hides inherited member [...]
   public string Name { set; }
   //... whatever
}

我当然不打算隐藏任何成员,所以这不好!

当然,我可以使用方法解决这个问题,但正确的选择是什么?我想保持“核心”接口尽可能小,即使分割接口除了传递意图之外没有任何其他目的。使用拆分接口,很明显哪些方法不会进行任何更新,并且它使编写代码更清晰(更不用说还允许使用简单的静态单例存根,这对于很多简单的情况就足够了)

我想避免任何抽象类等;他们重新实现或快速单一用途垫片更加复杂和难以理解。

那么,想法?

4 个答案:

答案 0 :(得分:28)

隐藏在界面中的方法几乎不那么蹩脚;我会选择类似的东西:

interface IBasicProps {
   int Priority { get; }
   string Name {get;}
   //... whatever
}

interface IBasicPropsWriteable:IBasicProps  {
   new int Priority { get; set; }
   new string Name { get; set; }
   //... whatever
}
class Foo : IBasicPropsWriteable {
    public int Priority {get;set;}
    public string Name {get;set;}
/* optional
    int IBasicProps.Priority {get {return Priority;}}
    string IBasicProps.Name {get {return Name;}}
*/
}

答案 1 :(得分:4)

如果您的目标是在允许阅读和写作时更清楚,那么我会使用单独的getter和setter方法而不是属性。

interface IBasicProps {
   int GetPriority();
   string GetName();
   //... whatever
}

interface IBasicPropsWriteable:IBasicProps  {
   void SetPriority(int priority);
   void SetName(string name);
   //... whatever
}

答案 2 :(得分:2)

一种方法是简单地跳过接口的继承。创建一个只读接口和一个只写接口,并根据需要实现:

interface IBasicPropsReadable {
   int Priority { get; }
   string Name { get; }
}

interface IBasicPropsWriteable  {
   int Priority { set; }
   string Name { set; }
}

class SomeClassReadWrite : IBasicPropsReadable, IBasicPropsWriteable {
    int Priority { get; set; }
    string Name { get; set; }
}

class SomeClassReadOnly : IBasicPropsReadable {
    int Priority { get; }
    string Name { get; }
}

答案 3 :(得分:1)

您可以让接口无关,只需让您的类实现两个接口。在所有接口简单地定义合同之后,合同不需要相关。看起来它只是一个优化,在编码时可写入的一个派生自另一个,所以你只需要指定一个接口。

public interface IBasicProps
{
   int Priority { get; }
   string Name {get;}
   //... whatever
}

public interface IBasicPropsWriteable
{
   int Priority { get; set; }
   string Name { get; set; }
   //... whatever
}

public class Foo : IBasicProps, IBasicPropsWriteable
{
   public int Priority { get; set; }
   public string Name { get; set; }

   // whatever
}

如果你真的需要优化,你可以创建另一个从两者派生的接口,让你的类实现它。

public interface IBasicPropsAll : IBasicProps, IBasicPropsWriteable  { }

public class Foo : IBasicPropsAll
{
   public int Priority { get; set; }
   public string Name { get; set; }

   // whatever
}