在 C# 中使用基 class 和基接口
Using base class and base interface in C#
我正在重塑不使用基本 classes 和基本接口的整个系统。
我这样做的想法是将所有常用方法提取到基础 classes 和基础接口中。
所以基本上,我们会有:
实现接口的基础classSomeClassBase
ISomeClassBase
派生的 class SomeClassDerived 实现 ISomeClassDerived
(此接口派生自 ISomeClassBase
)
现在的问题是,我如何在派生的 class 中实例化“_mySession”(它与基 class 中的转换不同),同时保留基 class 中的所有方法=37=]:
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
。
不要重新定义_mySession
让它来自基class。
但是在 Derived class 中,您仍然可以重新分配。
public class SomeClassDerived : SomeClassBase, ISomeClassDerived
{
public SomeClassDerived ()
{
_mySession = MySession.Instance(); //Declaration comes from base class automatically
_mySession.connect();
}
public void doSomethingElse()
{
_mySession.doSomethingElse();
}
}
如果您的 IMySessionBase
和 IMySessionDerived
遵循层次结构,它应该可以工作。但在极少数情况下,您可能最终会遇到 DoubleDispatchProblem。
正如评论中指出的那样,如果您想从 IMySessionDerived
开始做某事,您可以添加一个 属性。
public class SomeClassDerived : SomeClassBase, ISomeClassDerived
{
IMySessionDerived _derivedSessionAccessor=> _mySession as IMySessionDerived;
}
更新:要解决此处的确切设计问题,
不要从基础 class 派生,而是将其作为字段。并继承接口。因此,与其采用上述方法,
喜欢,
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();
}
}
粘贴@Selvin 的回答而不是埋在评论中的link:
这里的技巧是使用关键字 "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();
}
}
}
我正在重塑不使用基本 classes 和基本接口的整个系统。
我这样做的想法是将所有常用方法提取到基础 classes 和基础接口中。
所以基本上,我们会有:
实现接口的基础class
SomeClassBase
ISomeClassBase
派生的 class SomeClassDerived 实现
ISomeClassDerived
(此接口派生自ISomeClassBase
)
现在的问题是,我如何在派生的 class 中实例化“_mySession”(它与基 class 中的转换不同),同时保留基 class 中的所有方法=37=]:
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
。
不要重新定义_mySession
让它来自基class。
但是在 Derived class 中,您仍然可以重新分配。
public class SomeClassDerived : SomeClassBase, ISomeClassDerived
{
public SomeClassDerived ()
{
_mySession = MySession.Instance(); //Declaration comes from base class automatically
_mySession.connect();
}
public void doSomethingElse()
{
_mySession.doSomethingElse();
}
}
如果您的 IMySessionBase
和 IMySessionDerived
遵循层次结构,它应该可以工作。但在极少数情况下,您可能最终会遇到 DoubleDispatchProblem。
正如评论中指出的那样,如果您想从 IMySessionDerived
开始做某事,您可以添加一个 属性。
public class SomeClassDerived : SomeClassBase, ISomeClassDerived
{
IMySessionDerived _derivedSessionAccessor=> _mySession as IMySessionDerived;
}
更新:要解决此处的确切设计问题,
不要从基础 class 派生,而是将其作为字段。并继承接口。因此,与其采用上述方法,
喜欢,
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();
}
}
粘贴@Selvin 的回答而不是埋在评论中的link:
这里的技巧是使用关键字 "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();
}
}
}