【问题标题】:How can I call a method inherited from an interface directly from a class?如何直接从类调用从接口继承的方法?
【发布时间】:2022-01-21 14:15:48
【问题描述】:
using System;

interface ISample{
  abstract void SampleMethod();
}

class SampleClass: ISample{
  void ISample.SampleMethod(){
    Console.WriteLine("SampleMethod was called.");
  }
}

class Program{
  public static void Main (string[] args){
    SampleClass smpcls = new SampleClass();
    smpcls.ISample.SampleMethod();
  }
}

此代码可以无缝运行。但是我必须从“SampleClass”的实例“smpcls”中调用“ISample”接口。如何直接从“SampleClass”实例调用“SampleMethod”?

例如:

...
SampleClass smpcls = new SampleClass();
smpcls.SampleMethod() //I would like to call it like this.
smpcls.ISample.SampleMethod() //Not like this
...

【问题讨论】:

  • 接口中不能有抽象方法
  • 如果方法是这样实现的,您必须在访问该方法之前将类实例强制转换为接口。相反,为什么不直接将其设为公共方法,而不是显式实现接口的该方法?
  • 当他们在 C# 8 中添加默认接口方法时,他们还添加了对显式访问修饰符的支持。尽管abstract 是默认值,但实际上您现在可以显式指定它。但它并没有改变任何东西,该成员的行为就像它自 C# 1 以来的行为一样。

标签: c# .net class interface implementation


【解决方案1】:

为什么不用这个

void Main()
{
    SampleClass smpcls = new SampleClass();
    smpcls.SampleMethod();
}

public interface ISample
{
    public void SampleMethod();
}

public class SampleClass : ISample
{
    public void SampleMethod()
    {
        Console.WriteLine("SampleMethod was called.");
    }
}

或者如果你有 c# 8+ 也许你的意思是这个

SampleClass smpcls = new SampleClass();
smpcls.AsISampleMethod();

//or if you don't want to create an extra method

smpcls.AsISample.SampleMethod();


public interface ISample
{
    void SampleMethod()
    {
        Console.WriteLine("SampleMethod was called.");
    }
}
public class SampleClass : ISample
{
    public ISample AsISample => (ISample)this;

    public void AsISampleMethod()
    {
        AsISample.SampleMethod();
    }
}

但接口的工作方式几乎与抽象类相同

【讨论】:

  • 并去掉ISampleSampleMethod 上的abstract 修饰符。我很惊讶甚至编译
  • @Flydog57 谢谢。我同意你的看法。
  • abstract 是接口中方法的默认修饰符,你可以认为它在那些年默默地存在。当使用 C# 8 添加默认接口实现时,它们还允许显式修饰符,包括抽象。但是,根据文档,abstract 修饰符,无论是否存在,都没有任何影响。它的存在是为了完整性。
【解决方案2】:

SampleClass explicitly implementsISample.SampleMethod,这不是你想要的。只需将其更改为

class SampleClass: ISample{
  void SampleMethod(){
    Console.WriteLine("SampleMethod was called.");
  }
}

【讨论】:

    【解决方案3】:

    您必须将其转换为接口才能访问显式实现的接口方法

    ISample smpcls = new SampleClass();
    smpcls.SampleMethod();
    

    【讨论】:

      【解决方案4】:

      你要知道在实现接口的成员时有两种方式:

      1. 实现接口

      2. 显式实现接口

      在您的示例中,您已明确选择了实现接口

      void ISample.SampleMethod()
      

      如果你使用这个选项,那么你告诉类方法 void ISample.SampleMethod() 属于接口而不是类。

      为什么以及何时可以使用显式选项?好吧,假设你的类中有另一个方法,它被称为 SampleMethod() 现在,如果您实现 ISample,那么您将与此方法发生冲突,因为 ISample 包含具有相同名称的方法。因此,为了解决这个问题,您可以在接口方法上使用显式选项。

      public class SampleClass : ISample
      {
          void ISample.SampleMethod()
          {
              Console.WriteLine("interface method");
          }
      
          public void SampleMethod()
          {
              Console.WriteLine("class method");
          }
      }
      

      在您的调用代码中,这是您调用每个方法的方式:

                 SampleClass smpcls = new SampleClass();
                 smpcls.SampleMethod();
                 ((ISample)smpcls).SampleMethod();
      

      如你所见:((ISample)smpcls).SampleMethod(); 这属于接口,因为您必须将其转换为它。

      两种方法的输出如下:

      //class method
      //interface method
      

      如果您没有冲突的方法,则使用“实现接口”选项,它将声明没有接口名称的代码:

      public class SampleClass : ISample
      {
          public void SampleMethod()
          {
              Console.WriteLine("now this method belongs to the class");
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2021-06-23
        • 1970-01-01
        • 2019-12-22
        • 1970-01-01
        • 2013-02-25
        • 2012-03-29
        • 2013-02-06
        • 2014-04-18
        • 1970-01-01
        相关资源
        最近更新 更多