在C#中使用基类和基接口

问题描述 投票:-3回答:2

我正在重塑整个不使用基类和基接口的系统。

我这样做的想法是将所有常用方法提取到基类和基接口。 所以基本上,我们会:

  • 实现接口SomeClassBase的基类ISomeClassBase
  • 实现ISomeClassDerived的派生类SomeClassDerived(此接口派生自ISomeClassBase

现在问题是,我如何在派生类中实例化“_mySession”(它具有与基类不同的强制转换),同时保留基类中的所有方法:

public class SomeClassBase : ISomeClassBase 
{
 public IMySessionBase _mySession = MySession.Instance();

 public SomeClassBase ()
 {
   _mySession.connect();  // Needed??
 }

 public void doSomething()
 {
  _mySession.doSomething();
 }
}

public class SomeClassDerived : SomeClassBase, ISomeClassDerived  
{
 public IMySessionDerived _mySession = MySession.Instance();

 public SomeClassDerived ()
 {
  _mySession.connect();
 }

 public void doSomethingElse()
 {    
  _mySession.doSomethingElse();
 }
}

还有一件事,IMySessionDerived实施IMySessionBase

c# inheritance interface multiple-inheritance
2个回答
1
投票

粘贴@Selvin答案而不是评论中隐藏的链接: 这里的诀窍是使用关键字“base()”

using System;
using System.Runtime.CompilerServices;

public class Program
{
    public static void Main()
    {
        var o1 = new O1();
        o1.DS1();
        var o2 = new O2();
        o2.DS1();
        o2.DS2();
    }

    public class Session1
    {
        protected readonly Type ownerType;
        public Session1(Type type)
        {
            ownerType = type;
        }

        public virtual void DS1([CallerMemberName] string functionName = "")
        {
            Console.WriteLine(ownerType.Name + ":" +  GetType().Name + ":" + functionName);
        }       
    }

    public class Session2 : Session1
    {
        public Session2(Type type):base(type) { }

        public virtual void DS2([CallerMemberName] string functionName = "")
        {
            Console.WriteLine(ownerType.Name + ":" +  GetType().Name + ":" + functionName);
        }   
    }

    public class O1
    {
        private readonly Session1 t;

        public O1() : this(new Session1(typeof(O1))) { }
        protected O1(Session1 t)
        {
            this.t = t;
        }
        public void DS1()
        {
            t.DS1();
        }
    }

    public class O2 : O1
    {
        private readonly Session2 t;

        public O2() : this(new Session2(typeof(O2))) { }
        protected O2(Session2 t) : base(t)
        {
            this.t = t;
        }

        public void DS2()
        {
            t.DS2();
        }
    }
}

0
投票

不要重新定义_mySession让它来自基类。但是在你的Derived课程中你仍然可以重新分配。

public class SomeClassDerived : SomeClassBase, ISomeClassDerived  
{
 public SomeClassDerived ()
 {
  _mySession = MySession.Instance(); //Declaration comes from base class automatically
  _mySession.connect();
 }

 public void doSomethingElse()
 {    
  _mySession.doSomethingElse();
 }
}

如果您的IMySessionBaseIMySessionDerived遵循Hierarchy,它应该有效。但在极少数情况下,您最终可能会进入DoubleDispatchProblem。

正如评论中指出的那样,如果你想从IMySessionDerived做一些事情,你可以添加一个属性。

public class SomeClassDerived : SomeClassBase, ISomeClassDerived  
{
    IMySessionDerived _derivedSessionAccessor=>  _mySession as IMySessionDerived;

}

更新:要解决这里的确切设计问题,

而不是从基类派生,而是将其作为字段。并继承自界面。所以不要采取上述方法,

喜欢,

public class SomeClassBase : ISomeClassBase 
{
 public IMySessionBase _mySession ;
 public SomeClassBase ( IMySessionBase session)
 {
   _mySession=session;
   _mySession.connect();  // Needed??
 }

 public void doSomething()
 {
  _mySession.doSomething();
 }
}

 public class SomeClassDerived : , ISomeClassDerived  
{
 public IMySessionDerived _mySession = MySession.Instance();
 private SomeClassBase _baseClassInstance;
 public SomeClassDerived ()
 {
   _baseClassInstance=new SomeClassBase(_mySession);
    //_mySession.connect();
 }

 public void doSomethingElse()
 {    
  _baseClassInstance.doSomethingElse();
 }
}
© www.soinside.com 2019 - 2024. All rights reserved.