为什么不能直接调用扩展方法?

发布于 2024-09-27 14:24:03 字数 437 浏览 3 评论 0原文

有人可以向我解释为什么下面第三次调用 DoSomething 无效吗? (错误消息是“名称‘DoSomething’在当前上下文中不存在”)

public class A { }
public class B : A
{
    public void WhyNotDirect()
    {
        var a = new A();
        a.DoSomething();  // OK
        this.DoSomething();  // OK
        DoSomething(); // ?? Why Not
    }
}
public static class A_Ext
{
    public static void DoSomething(this A a)
    {
        Console.WriteLine("OK");
    }
}

Can someone explain to me why in the following the 3rd invocation of DoSomething is invalid?
( Error message is "The name 'DoSomething' does not exist in the current context" )

public class A { }
public class B : A
{
    public void WhyNotDirect()
    {
        var a = new A();
        a.DoSomething();  // OK
        this.DoSomething();  // OK
        DoSomething(); // ?? Why Not
    }
}
public static class A_Ext
{
    public static void DoSomething(this A a)
    {
        Console.WriteLine("OK");
    }
}

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

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

发布评论

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

评论(4

好菇凉咱不稀罕他 2024-10-04 14:24:03

扩展方法可以像其他静态方法一样被调用。

将其更改为 A_Ext.DoSomething(this)

如果您问为什么它不在 this 上隐式调用,答案是规范就是这样编写的。我认为原因是在没有限定符的情况下调用它会太误导人。

Extension methods can be invoked like other static methods.

Change it to A_Ext.DoSomething(this).

If you're asking why it isn't implicitly invoked on this, the answer is that that's the way the spec was written. I would assume that the reason is that calling it without a qualifier would be too misleading.

儭儭莪哋寶赑 2024-10-04 14:24:03

因为 DoSomething 需要一个参数。

DoSomething(a) 是合法的。

编辑

我在这里读到的问题有点错误。

由于您将其称为普通静态方法,而不是扩展方法,因此您需要在类名前加上前缀。

所以 A_Ext.DoSomething(a); 会起作用。

如果您像普通静态方法一样调用它,则所有相同的规则都适用。

您的第二个变体有效,因为 B 继承 A,因此您最终仍然将其作为扩展方法调用,但第三个变体则不然。

对于上面的第一个版本无法工作感到抱歉。我将保留它以保持评论的相关性。

Because DoSomething takes a parameter.

DoSomething(a) would be legal.

Edit

I read the question a bit wrong here.

Since your calling it a a normal static method, and not a extension method, you need to prefic with the class name.

So A_Ext.DoSomething(a); will work.

If you call it like a normal static method, all the same rules apply.

Your second variant works because B inhetits A, and therefore you still end up calling it as an extension method, but the third does not.

sorry about the first version above that does not work. I'll leave it to keep the comment relevant.

静谧 2024-10-04 14:24:03

扩展方法仍然是静态方法,而不是真正的实例调用。为了使其工作,您需要使用实例方法语法的特定上下文(来自 扩展方法(C# 编程指南))

在您的代码中调用扩展
具有实例方法语法的方法。
然而,中间语言
(IL) 由编译器生成
将您的代码转换为对
静态方法。因此,
封装的原理不是
确实被侵犯了。实际上,
扩展方法无法访问
私有变量的类型
延伸。

因此,虽然通常情况下,两种语法都可以工作,但第二种语法没有显式上下文,并且生成的 IL 似乎无法隐式获取上下文。

Extension methods are still static methods, not true instance calls. In order for this to work you would need specific context using instance method syntax (from Extension Methods (C# Programming Guide))

In your code you invoke the extension
method with instance method syntax.
However, the intermediate language
(IL) generated by the compiler
translates your code into a call on
the static method. Therefore, the
principle of encapsulation is not
really being violated. In fact,
extension methods cannot access
private variables in the type they are
extending.

So while normally, both syntaxes would work, the second is without explicit context, and it would seem that the IL generated can't obtain the context implicitly.

第七度阳光i 2024-10-04 14:24:03

DoSomething 需要 A 的实例来执行任何操作,如果没有限定符,编译器将无法查看您需要调用哪个 DoSomething。它不知道要签入您的方法的 A_Ext ,除非您使用 this 对其进行限定。

DoSomething requires an instance of A to do anything, and without a qualifier, the compiler can't see which DoSomething you need to invoke. It doesn't know to check in A_Ext for your method unless you qualify it with this.

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