为什么 AC# 类可以隐式和显式地从一个接口继承?

发布于 2024-07-07 20:24:00 字数 732 浏览 13 评论 0原文

今天我偶然发现一个C#类可以以隐式和显式的方式继承一个接口。 这让我很惊讶。 如果 C# 以这种方式工作,那么当以不同方式引用时,一个实例的行为可能会有所不同。

interface IFoo
{
    void DoSomething();
}

class Foo : IFoo
{
    #region IFoo Members
    public void DoSomething()
    {
        Console.WriteLine("do something implicitly");
    }
    #endregion

    #region IFoo Members
    void IFoo.DoSomething()
    {
        Console.WriteLine("do something explicitly");
    }
    #endregion
}


        Foo f = new Foo();
        f.DoSomething();

        ((IFoo)f).DoSomething();

上面的代码运行并输出

do something implicitly
do something explicitly

我认为 C# 的这种设计导致行为不一致。 也许一个 C# 类必须以隐式或显式方式从一个接口继承,但不能同时继承这两种方式。

C#这样设计有什么原因吗?

Today I happens to find that one C# class can inherit one interface both in implicit and explicit way. This surprises me. If C# works in this way, then one instance can behave differently when referenced in different way.

interface IFoo
{
    void DoSomething();
}

class Foo : IFoo
{
    #region IFoo Members
    public void DoSomething()
    {
        Console.WriteLine("do something implicitly");
    }
    #endregion

    #region IFoo Members
    void IFoo.DoSomething()
    {
        Console.WriteLine("do something explicitly");
    }
    #endregion
}


        Foo f = new Foo();
        f.DoSomething();

        ((IFoo)f).DoSomething();

Above code runs and output

do something implicitly
do something explicitly

I believe that this design of C# make inconsistency of behavior. Perhaps it is mandatory that one C# class can inherit from one interface in implicit or expliict way, but not both.

Is there any reason that why C# is designed in such a way?

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

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

发布评论

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

评论(5

陪你到最终 2024-07-14 20:24:00

每个实现接口的类在该类的成员和接口的成员之间都有一个映射。 如果类显式实现接口成员,则显式实现将始终映射到接口。 如果没有显式实现,则需要隐式实现,并且该实现将映射到接口。

当一个类具有与接口相同的成员名称和关联类型它也显式实现该接口的相应成员时,则该类的“隐式”实现不是 根本认为是接口的实现(除非显式实现调用它)。

除了在类实现具有相同成员名称/类型的多个接口的每种情况下的不同含义之外,即使只有一个接口,类本身也被认为具有一个隐式接口,该隐式接口可能具有相同的成员名称/类型。成员/类型作为唯一的接口,但仍然意味着不同的东西。

Every class that implements an interface has a mapping between that class's members and the interface's members. If the class explicitly implements an interface member, then the explicit implementation will always be mapped to the interface. If there isn't an explicit implementation then an implicit implementation is expected, and that one will be mapped to the interface.

When a class has the same member name and associated types as an interface but it also explicitly implements the corresponding member for the interface, then the class's "implicit" implementation isn't considered an implementation of the interface at all (unless the explicit implementation calls it).

In addition to different meanings in each case where the class implements multiple interfaces with the same member name/types, even with only one interface, the class itself is considered to have an implicit interface which might have the same member/types as the sole interface but still mean something different.

深海夜未眠 2024-07-14 20:24:00

您的示例没有隐式和显式实现 IFoo。 您只需显式实现 IFoo.DoSometing() 即可。 您的类中有一个名为 DoSomething() 的新方法。 它与 IFoo.DoSomething 无关,只是名称和参数相同。

Your example does not implement IFoo both implicitly and explicitly. You only implement IFoo.DoSometing() explicitly. You have a new method on your class called DoSomething(). It has nothing to do with IFoo.DoSomething, except that it has the same name and parameters.

起风了 2024-07-14 20:24:00

这使得在发生碰撞时更加灵活。 特别是,请查看 IEnumeratorIEnumerator-它们都有一个 Current 属性,但类型不同。 您必须使用显式接口实现来实现两者(并且通用形式扩展了非通用形式)。

This makes it more flexible for when there are collisions. In particular, look at IEnumerator and IEnumerator<T> - they both have a Current property, but of different types. You have to use explicit interface implementation in order to implement both (and the generic form extends the non-generic form).

月亮坠入山谷 2024-07-14 20:24:00

多重继承:
如果您从为不同目的定义相同方法的两个接口派生怎么办?

  interface IMoveable
  {
    public void Act();
  }

  interface IRollable
  {
    public void Act();
  }

  class Thing : IMoveable, IRollable
  {
    //TODO Roll/Move code here

    void IRollable.Act()
    {
      Roll();
    }

    void IMoveable.Act()
    {
      Move();
    }
  }

Multiple inheritance :
What if you derive from two interfaces defining same method for different purposes?

  interface IMoveable
  {
    public void Act();
  }

  interface IRollable
  {
    public void Act();
  }

  class Thing : IMoveable, IRollable
  {
    //TODO Roll/Move code here

    void IRollable.Act()
    {
      Roll();
    }

    void IMoveable.Act()
    {
      Move();
    }
  }
云柯 2024-07-14 20:24:00

伙计们,谢谢你们的回答。

事实证明,“C#类可以同时以隐式和显式方式继承一个接口”实际上是一种幻想。 实际上,一个类可以一次性继承一个接口。

在原来的问题中,“DoSomething”方法似乎“隐式实现”接口IFoo(该方法实际上是由VS2008生成的),但实际上不是。 通过显式实现接口 IFoo,“DoSomething”方法就变成了普通方法,除了具有相同的签名之外,与 IFoo 无关。

我仍然认为这是C#的一个棘手的设计,并且很容易被错误地使用。 比如说,我有一些像这样的代码

        Foo f = new Foo();
        f.DoSomething();

现在,我想将其重构为下面的代码。 看起来完全没问题,但是执行结果却不同。

        Action<IFoo> func = foo => foo.DoSomething();
        func(f);

Guys, Thanks for your answers.

It turns out that "C# class can inherits one interface in both implicit and explicit way at same time" is actually a illusion. Actually, one class can inherit one interface for one time.

In the original question, the "DoSomething" method seems "implicitly implement" interface IFoo (the method is actually generated by VS2008), but it is actually NOT. With explicit implementation of interface IFoo, the "DoSomething" method turns to be just normal method which has nothing to do with IFoo except with same signature.

I still believe it is a tricky design of C#, and it is easy to use it mistakenly. Say, I have some code like this

        Foo f = new Foo();
        f.DoSomething();

Now, I want to refactor it to below code. It seems perfectly OK, but the execution result is different.

        Action<IFoo> func = foo => foo.DoSomething();
        func(f);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文