如何直接从类调用从接口继承的方法?

Posted

技术标签:

【中文标题】如何直接从类调用从接口继承的方法?【英文标题】: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 以来的行为一样。 【参考方案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】:

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

    实现接口

    显式实现接口

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

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");
    

【讨论】:

以上是关于如何直接从类调用从接口继承的方法?的主要内容,如果未能解决你的问题,请参考以下文章

python如何从类体内调用静态方法[重复]

Grails / Spock:如何在类中模拟从类本身调用方法的单个方法?

我如何知道哪些类从类或接口继承? [复制]

Child extends Parent,可以得到什么?

Lua继承和方法

Mixin覆盖继承的方法