奇怪的继承修改

发布于 2024-12-12 02:01:25 字数 783 浏览 0 评论 0原文

我是一名 .NET 开发人员,对 OOP 非常了解。 然而,最近我注意到一个有趣的事实。

System.Data.SqlClient.SqlCommand 派生自 System.Data.Common.DbCommand。后者实现了System.IDbCommandSystem.IDbCommand 公开属性 Connection,它是 IDbConnection 的实例。 在 DbCommand 中,此属性返回 DbConnection 类型。最后,SqlCommand 中的相同属性的类型为 SqlConnection

我尝试执行相同的操作,但它给出了编译时错误。在上面的示例中这是如何实现的以及如何重新创建相同的模式?

我的代码(未编译):

public interface IFoo { }
public interface IBar 
{
   IFoo TheFoo();
}

public abstract class AbsFoo : IFoo { }
public abstract class AbsBar : IBar 
{
    public abstract AbsFoo TheFoo();
}

public class ConcreteFoo : AbsFoo { }
public class ConcreteBar : AbsBar { }

I'm a .NET developer and know pretty much about OOP.
However, recently I noticed one interesting fact.

System.Data.SqlClient.SqlCommand derives from
System.Data.Common.DbCommand. The latter implements System.IDbCommand.
System.IDbCommand exposes the property Connection which an instance of IDbConnection.
In DbCommand However this property returns DbConnection type. And finally the same property in SqlCommand is of type SqlConnection

I've tried to perform the same however it gave a compile time error. How was this achieved in above example and how can I recreate the same pattern?

My code (not compiling):

public interface IFoo { }
public interface IBar 
{
   IFoo TheFoo();
}

public abstract class AbsFoo : IFoo { }
public abstract class AbsBar : IBar 
{
    public abstract AbsFoo TheFoo();
}

public class ConcreteFoo : AbsFoo { }
public class ConcreteBar : AbsBar { }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

活雷疯 2024-12-19 02:01:25

显式接口实现是这里的游戏名称。试试这个:

public abstract class AbsBar : IBar {
    IFoo IFoo.TheFoo() { return this.TheFoo(); }
    public abstract AbsFoo TheFoo();
}

这是关于 隐式实现与显式实现

Explicit interface implementation is the name of the game here. Try this:

public abstract class AbsBar : IBar {
    IFoo IFoo.TheFoo() { return this.TheFoo(); }
    public abstract AbsFoo TheFoo();
}

Here's a good guide on implicit vs. explicit implementation.

海的爱人是光 2024-12-19 02:01:25

我不得不说,我认为理查德有点难受 - 他的回答和杰森一样好,因为他们都只回答了问题的一半。 将它们放在一起,您就得到了完整的答案。

要使用 IDbCommandDbCommandIDbCommand 来实现此操作,请执行以下操作: SqlCommandDbCommand 中必须有 IDbCommand 的显式实现(Jason 的回答),并且在 < code>SqlCommand(理查德的回答)。

我将给出完整的“Foo/Bar”示例。

从这些接口开始:

public interface IFoo
{
    IBar GetBar();
}

public interface IBar { }

接下来 Foo 必须提供 IFoo 的显式实现,以便返回 Bar,而不是 IBar ,来自其自己的 GetBar 方法:

public abstract class Foo : IFoo
{
    IBar IFoo.GetBar()
    {
        return this.GetBar();
    }

    public Bar GetBar()
    {
        return this.GetBarInner();
    }

    protected abstract Bar GetBarInner();
}

public abstract class Bar : IBar { }

最后,SomeFoo 类必须隐藏 GetBar 才能返回 SomeFoo实例:

public class SomeFoo : Foo
{
    public new SomeBar GetBar()
    {
        return new SomeBar();
    }

    protected override Bar GetBarInner()
    {
        return this.GetBar();
    }
}

public class SomeBar : Bar { }

我认为理查德唯一的信息是我添加了new 关键字添加到隐藏方法中,可以消除编译器错误。

I have to say that I think Richard was a little hard done by - his answer is just as good as Jason's in that they both only answered half of the question. Put them both together and you have the full answer.

To make this work with IDbCommand, DbCommand & SqlCommand there has to be an explicit implementation of IDbCommand in DbCommand (Jason's answer) and public method shadowing in SqlCommand (Richard's answer).

I'll give the full "Foo/Bar" example.

Start with these interfaces:

public interface IFoo
{
    IBar GetBar();
}

public interface IBar { }

Next Foo must provide an explicit implementation of IFoo in order to return Bar, not IBar, from its own GetBar method:

public abstract class Foo : IFoo
{
    IBar IFoo.GetBar()
    {
        return this.GetBar();
    }

    public Bar GetBar()
    {
        return this.GetBarInner();
    }

    protected abstract Bar GetBarInner();
}

public abstract class Bar : IBar { }

And finally a SomeFoo class must shadow GetBar to be able to return a SomeFoo instance:

public class SomeFoo : Foo
{
    public new SomeBar GetBar()
    {
        return new SomeBar();
    }

    protected override Bar GetBarInner()
    {
        return this.GetBar();
    }
}

public class SomeBar : Bar { }

I think the only information that Richard is that my adding the new keyword to the shadowed method you get rid of the compiler error.

撩发小公举 2024-12-19 02:01:25

DbCommand 和 SqlCommand 中的 Connection 都只是公共方法。会有编译器警告,但这是允许的。您的代码应该更像这样才能像 SqlCommand/DbCommand 一样工作:

    public interface IFoo { }
public abstract class AbsBaseBar
{
    public IFoo TheFoo() { throw new NotImplementedException(); }
}
public class AbsFoo : IFoo { }
public class AbsBar : AbsBaseBar
{
    public AbsFoo TheFoo() { throw new NotImplementedException(); }
}

public class ConcreteFoo : AbsFoo { }
public class ConcreteBar : AbsBar { } 

Connection in DbCommand and SqlCommand are both just public methods. There would be a compiler warning, but it's allowed. Your code should be more like this to work like SqlCommand/DbCommand:

    public interface IFoo { }
public abstract class AbsBaseBar
{
    public IFoo TheFoo() { throw new NotImplementedException(); }
}
public class AbsFoo : IFoo { }
public class AbsBar : AbsBaseBar
{
    public AbsFoo TheFoo() { throw new NotImplementedException(); }
}

public class ConcreteFoo : AbsFoo { }
public class ConcreteBar : AbsBar { } 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文