扩展方法和静态方法有什么区别?

时间:2013-10-02 16:40:29

标签: c# .net extension-methods static-methods

扩展方法和静态方法有什么区别?

我有两个这样的课程:

public static class AClass {
    public static int AMethod(string ....)
    {
    }
}

public static class BClass {
    public static int BMethod(this string ....)
    {
    }
}

我可以使用这些

AClass.AMethod('...');

'...'.BMethod();

提议哪个?

2 个答案:

答案 0 :(得分:28)

扩展方法仍然是一种静态方法。您可以完全按照常规静态方法使用它。

唯一的区别是扩展方法允许您以类似于该类型的方式使用该方法,因此您可以编写:

int result = stringValue.BMethod();

而不是:

int result = BClass.BMethod(stringValue);

这纯粹作为编译“技巧” - 编译器看到第一个表单,如果BClass可用(它有一个正确的using并且在引用的程序集中),那么它会把它变成第二种方法的IL给你。这纯粹是一种便利。

  

提议哪个?

这实际上取决于。如果您控制类型,我建议将方法放在类型本身上。这通常更易于维护。

如果你不控制类型,或者你试图“扩展”一个普通类型(例如IEnumerable<T>),那么扩展方法可能是一种合理的方法。

但是,如果类型是一种非常常见的类型,我通常会避免使用扩展方法,因为它们在智能感知中会变成“噪音”,这反过来会导致额外的混淆。例如,我个人不建议在System.ObjectSystem.String等处添加扩展程序。

答案 1 :(得分:1)

您无法覆盖扩展方法。 只有当方法具有不同的签名时,它才会被重载。

当然有一些限制: 扩展方法必须作为静态方法和静态类实现(在非嵌套的非泛型静态类中更精确)。 您可以使用扩展方法来扩展类或接口,但不能覆盖它们。永远不会调用与接口或类方法具有相同名称和签名的扩展方法。在编译时,扩展方法的优先级始终低于类型本身中定义的实例方法。 扩展方法无法访问它们正在扩展的类型中的私有变量。 您可以将扩展方法视为向现有类添加更多静态方法而不实际继承它们的“合法”方法。 但有趣的是,与类的常规静态方法不同,您不能在类级别上调用扩展方法(如果您尝试这样做,您将收到编译时错误),但您必须在类的实例上调用它们(好像它们是该类实例的常规方法,它们不是!!!)。

此外,在扩展方法中,您可以自由使用调用该方法的传递对象实例的公共属性,但这并不仅限于静态对象数据。只有Extension方法是静态方法,但调用的对象是完整的常规对象实例。