所以这个问题是一个明确的案例,一石二杀(一个设计和代码问题)我有一个基类,它有一个基本接口
interface IBase
{
IBase Method1();
}
abstract class Base : IBase
{
IBase Method1()
{
//do work
return this;
}
}
现在是子类
interface IChild1 : IBase
{
IChild1 ChildMethod();
}
class Child1 : Base, IChild1
{
public IChild1 ChildMethod()
{
//do work
// this would work fine Method1(); ChildMethod2();
//but I want to chain methods
Method1().ChildMethod2();
return this;
}
void ChildMethod2()
{
//do work
}
}
问题的关键是我希望基类返回子类实例。从ChildMethod()方法中的代码可以看出,基类方法Method1()返回IBase的实例,因此无法链接ChildMethod2()。是的,我可以在不必链接方法的情况下生活,但我们假设这是我唯一的选择。
这是我尝试使用泛型
interface IBase<T> where T : IBase<T>
{
T Method1();
}
abstract class Base<T> : IBase<T> where T : Base<T>
{
public T Method1()
{
//do work
return (T)this;
}
}
interface IChild1 : IBase<IChild1>
{
IChild1 ChildMethod();
}
class Child1 : Base<Child1>, IChild1
{
public IChild1 ChildMethod()
{
//do work
Method1(); ChildMethod2();
return this;
}
void ChildMethod2()
{
//do work
}
}
为了清楚地说明我想要实现的是对于我对基类的每次调用(在这种情况下为接口)我希望返回调用类/接口。 注意:使用Autofac进行依赖项注入
答案 0 :(得分:0)
我认为你可以在保留接口和基类的同时这样做:
interface IBase<TSelf> where TSelf : IBase<TSelf> {
TSelf Method1();
}
interface IChild1 : IBase<IChild1> {
IChild1 ChildMethod();
void ChildMethod2();
}
class Base<TSelf> : IBase<TSelf> where TSelf : IBase<TSelf> {
public TSelf Method1() {
//do work
// need to double-cast here or just do
return (TSelf) (IBase<TSelf>) this;
}
}
class Child1 : Base<IChild1>, IChild1 {
public IChild1 ChildMethod() {
//do work
Method1().ChildMethod2();
return this;
}
public void ChildMethod2() {
//do work
}
}
但正如您在评论中指出的那样,这不会与继承树中的更多成员一起工作。如果你可以删除接口,你可以这样做:
public abstract class Base<TSelf> where TSelf : Base<TSelf> {
public TSelf Method1() {
//do work
// need to double-cast here or just do
return (TSelf) this;
}
}
internal class Child1Impl<TSelf> : Base<TSelf> where TSelf : Child1Impl<TSelf> {
public TSelf ChildMethod() {
//do work
Method1().ChildMethod2();
return (TSelf) this;
}
public void ChildMethod2() {
//do work
}
}
// create subclass for ease of use, so that caller should not do Child1Impl<Child1> every time
class Child1 : Child1Impl<Child1> {
}
class SubChild1Impl<TSelf> : Child1Impl<TSelf> where TSelf : SubChild1Impl<TSelf> {
public TSelf SubChildMethod() {
Method1().ChildMethod();
return (TSelf) this;
}
}
class SubChild1 : SubChild1Impl<SubChild1> {
}
然后你可以这样做:
var test = new SubChild1();
test.Method1().ChildMethod().SubChildMethod();
也许你可以以某种方式对接口做同样的事情,但代码已经相当复杂,接口会更复杂(你已经有了基类,所以也许你真的不需要那些接口)。 / p>