【问题标题】:In C# 8.0 is there a way to expose default member implementation on the class?在 C# 8.0 中有没有办法在类上公开默认成员实现?
【发布时间】:2019-12-03 14:17:56
【问题描述】:

在 C# 8.0 中,接口可以为某些成员提供默认实现。这些实现是明确的,意味着它们不能通过类实例访问,我们必须转换为接口类型才能调用它们。有没有办法在同名的类实例上公开这个实现?可以通过将 this 指针转换为接口类型并调用如下方法来以另一个名称公开它:

void A()
{
   ((ISomething)this).B();
}

但是我似乎无法找到一种方法来使用 B 的原始名称公开实现,因为如果我声明一个方法 B,它会被视为实现导致无限递归的接口的方法。有什么方法可以在不复制的情况下公开实现,或者我缺少什么?

为了澄清,我正在寻找一种实现类似特征的功能的方法,即能够将实现从接口直接导入类的公共 API 而无需更改方法名称(大概接口中的名称是最好的) )。问题不在于如何以类的用户身份调用该方法,而是如何使其成为该类的公共 API 的一部分。

扩展方法是一种解决方案,但默认接口实现可以访问受保护的成员并且可以重载。

【问题讨论】:

  • 评论不用于扩展讨论;这个对话是moved to chat
  • @SamuelLiew 没有这些 cmets,问题仍然会被关闭,没有人能够回答。正是这些 cmets 澄清了这个问题。是的,它们很多,但是是的,它们很重要
  • 太好了,请帮助编辑问题。
  • @Stilgar 您可以将 cmets 中的重要部分添加到问题中吗?
  • @PanagiotisKanavos 我添加了一个说明。您认为讨论中的其他问题对问题很重要吗?

标签: c# c#-8.0 default-interface-member


【解决方案1】:

一种可能性是为它们提供属性。当我需要从类中引用显式实现时,我会这样做。

class Something : IInterfaceA, IInterfaceB {
   public IInterfaceA A => this;
   public IInterfaceB B => this;
}

...

something.A.AMethod();
something.B.BMethod();

您也可以考虑使用扩展方法而不是默认实现。无论如何,它们有些相似。

interface IInterface {
}

static class IInterfaceExtensions {
   public static void DoSomething(
      this IInterface me
   ) {
      // do something
   }
}

【讨论】:

  • 扩展方法对类也有更多的访问权限。 OP 在现已删除的评论中提到 DIM 也可以访问受保护的方法,尽管这颠倒了实际关系 - DIM 增加了对这些方法的需求,它不仅可以访问它们
【解决方案2】:

没有简单的方法可以做到;各种丑陋的解决方法都可能归结为委托给其他方法(静态方法或依赖本身不实现该方法的辅助类)来访问它,即使那样你也需要以某种方式传递状态。有一个proposal 用于base(T) 语法draft specification here,它应该允许base(ISomething).B() 引用实现而不会导致循环引用。这原本计划成为 C# 8 的一部分,但事实证明这过于雄心勃勃,因此被删掉了。在撰写本文时,它是candidate for inclusion in C# 9

【讨论】:

    猜你喜欢
    • 2013-01-21
    • 2020-05-11
    • 1970-01-01
    • 1970-01-01
    • 2011-05-22
    • 1970-01-01
    • 1970-01-01
    • 2014-11-08
    相关资源
    最近更新 更多