在 C# 中从实现者调用接口扩展方法很奇怪

发布于 2024-09-19 12:59:40 字数 964 浏览 9 评论 0原文

从实现者调用在接口上工作的扩展方法似乎需要使用 this 关键字。这看起来很奇怪。

有谁知道为什么?

有没有更简单的方法来获得接口的共享实现?

这让我很恼火,因为我正在遭受多重继承/混合退出的痛苦。

玩具示例:

public interface ITest
{
    List<string> TestList { get; }
}

public static class TestExtensions
{
    private const string Old = "Old";
    private const string New = "New";

    public static void ManipulateTestList(this ITest test)
    {
        for (int i = 0; i < test.TestList.Count; i++)
        {
            test.TestList[i] = test.TestList[i].Replace(Old, New);
        }
    }
}

public class Tester : ITest
{
    private List<string> testList = new List<string>();
    public List<string> TestList
    {
        get { return testList; }
    }

    public Tester()
    {
        testList.Add("OldOne");
        testList.Add("OldTwo");

        // Doesn't work
        // ManipulateTestList();

        // Works
        this.ManipulateTestList();
    } 
}

Invoking an extension method that works on a interface from an implementor seems to require the use of the this keyword. This seems odd.

Does anyone know why?

Is there an easier way to get shared implementation for an interface?

This irks me as I'm suffering multiple inheritance/mixin withdrawl.

Toy example:

public interface ITest
{
    List<string> TestList { get; }
}

public static class TestExtensions
{
    private const string Old = "Old";
    private const string New = "New";

    public static void ManipulateTestList(this ITest test)
    {
        for (int i = 0; i < test.TestList.Count; i++)
        {
            test.TestList[i] = test.TestList[i].Replace(Old, New);
        }
    }
}

public class Tester : ITest
{
    private List<string> testList = new List<string>();
    public List<string> TestList
    {
        get { return testList; }
    }

    public Tester()
    {
        testList.Add("OldOne");
        testList.Add("OldTwo");

        // Doesn't work
        // ManipulateTestList();

        // Works
        this.ManipulateTestList();
    } 
}

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

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

发布评论

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

评论(3

如日中天 2024-09-26 12:59:40

我直接向语言团队询问了这个确切的问题。我手头没有电子邮件,但基本上答案(来自 Mads,IIRC)是:

  • 减少搜索空间/复杂性 - 即不必考虑所有可用的扩展方法(并修剪它们),除非首先有表达式。
  • 减少扩展方法意外地“接管”常规方法(即更好的匹配)的机会就

我个人而言,我希望它能够一致地工作 - 第一个似乎不是一个大问题(但是,我不不编写编译器),并且都不接近这样一个事实:通常 this.* 是一个可选的东西(可能会产生诸如本地代码风格指南之类的影响,即“你应该使用这个。”)。

I asked this exact question to the language team directly. I don't have the e-mail to hand, but basically the answer (from Mads, IIRC) was that it is:

  • to reduce the search-space / complexity - i.e. not having to consider all available extension methods (and prune them) unless there is the expression first.
  • to reduce the chance of an extension method "taking over" a regular method (i.e. being a better match) unexpectedly

Personally, I'd have liked it to work consistently - the first doesn't seem a big problem (but then, I don't write compilers), and neither approaches the fact that normally this.* is an optional thing (that may have influences such as local code style guidelines, i.e. "thou shalt use this.").

七七 2024-09-26 12:59:40

语言规范中的相关部分说:

7.6.5.2 扩展方法调用

在方法调用(§7.5.5.1)中
其中一种形式

  • expr . 标识符 ( )
  • expr . 标识符 ( args )
  • expr . 标识符 < typeargs >< /code> ( )
  • expr . 标识符 < typeargs >< /code> ( args )

如果正常处理
调用发现不适用
方法,尝试处理
作为扩展方法的构造
调用。如果expr或任何args
具有编译时类型dynamic
扩展方法将不适用。

这清楚地表明扩展方法只能在表达式 (expr) 上调用。当然,这个表达式可以是“this”,但它必须存在。

The relevant section in the language specification says:

7.6.5.2 Extension method invocations

In a method invocation (§7.5.5.1) of
one of the forms

  • expr . identifier ( )
  • expr . identifier ( args )
  • expr . identifier < typeargs > ( )
  • expr . identifier < typeargs > ( args )

if the normal processing of the
invocation finds no applicable
methods, an attempt is made to process
the construct as an extension method
invocation. If expr or any of the args
has compile-time type dynamic,
extension methods will not apply.

This clearly says that extension methods can only be invoked on an expression (expr). This expression can, of course, be “this”, but it must be present.

长亭外,古道边 2024-09-26 12:59:40

扩展方法是一种编译器技巧,适用于将调用重定向到另一个静态类中的静态方法的对象。 '这。是编译器传递静态方法的对象。非工作示例只是编译器告诉您该方法不是并且实例方法的范围仅限于该类。

Extension methods are a compiler trick that work on an object that redirect the call to a static method in another static class. 'this. is the object, that the compiler passes the static method. The non working example is simply the compiler telling you that the method is not and instance method scoped to the class.

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