代码之家  ›  专栏  ›  技术社区  ›  James

如何使用类作为基类,但公开隐藏类类型?

c#
  •  1
  • James  · 技术社区  · 14 年前

    我目前只是通过一个通用接口来公开这些属性。

    public interface IBaseClass
    {
        int ID { get; set; }
    }
    
    internal class MyBaseClass : IBaseClass
    {
        public MyBaseClass() { }
        public int ID { get; set; }
    }
    
    public class MyExposedClass : IBaseClass
    {
        private MyBaseClass _base = new MyBaseClass();
    
        public int ID
        {
            get { return _base.ID; }
            set { _base.ID = value; }
        }
    }
    

    然后在我的主应用程序中,我可以:

    IBaseClass c = new MyExposedClass();
    c.ID = 12345;
    

    但做不到:

    MyBaseClass b = new MyBaseClass();
    

    这是我想要的行为。

    然而,我只是想知道这是不是正确的方法?或者有更好的办法?

    7 回复  |  直到 14 年前
        1
  •  6
  •   Darin Dimitrov    14 年前

    如果你只想阻止实例化 MyBaseClass 抽象(使它的构造器也受到保护-这是一个好的设计)并且 MyExposedClass 从中汲取。如果你想完全隐藏这种类型,你的方法看起来不错。

        2
  •  1
  •   Preet Sangha    14 年前

    我看这个不错。使用小接口可以更容易地编写分离代码。

        3
  •  1
  •   Josh Smeaton    14 年前

    我不知道这是否有用,但你可以让你的基类内部受到保护。这意味着任何内部类都可以访问它,就好像它是公共的一样,或者任何类(从程序集内部和外部)都可以对基类进行子类化。但这不会阻止人们实现自己的子类。

    或者,通过一个接口公开是我认为最好的方式。

        4
  •  1
  •   Community CDub    7 年前

    为此,您可以选择如下显式实现:

    public interface IBaseClass
    {
        int ID { get; set; }
    }
    
    internal class MyBaseClass : IBaseClass
    {
        public MyBaseClass() { }
        public int IBaseClass.ID { get; set; }
    }
    
    public class MyExposedClass : IBaseClass
    {
        private MyBaseClass _base = new MyBaseClass();
    
        public int IBaseClass.ID
        {
            get { return _base.ID; }
            set { _base.ID = value; }
        }
    }
    

    你可以参考类似的帖子 C# Interfaces. Implicit implementation versus Explicit implementation

        5
  •  0
  •   David Neale    14 年前

    把你的基类抽象化。

        6
  •  0
  •   DaeMoohn    14 年前

    您可以将接口公开为公共的,实现该类的内部密封实现,并使用工厂方法构建所需接口的实例。这样,客户机永远不会知道您何时更改实现,或者您是否在工厂中插入了同一基本接口的多个实现。您还可以消除接口中的set访问器,并将它们放在内部实现中,以便只向外部公开属性。这样,外部代码就可以减少对实现的假设,并且可以更好地隔离。如果我对这种方法的印象不好,请纠正我。

    编辑:工厂将是公共的,您需要某种“传输对象”来向工厂传递数据。传输对象实现将是公共的,以及它的接口。

        7
  •  0
  •   mP.    14 年前

    你的例子似乎包括了一个利用遗传优势的糟糕例子。因为你只包含了一个属性,而且无法给出更好的例子,所以我猜它是真的。在这种情况下,我建议忘记基类并将属性粘在派生的上。