扩展方法是否类似于在c#中使用“new”关键字方法?

时间:2012-04-08 16:43:33

标签: c# .net inheritance extension-methods new-operator

我们可以在扩展方法和继承之间建立一些关系吗?

或者是一种类似于在C#中使用new - 关键字的扩展方法吗?

4 个答案:

答案 0 :(得分:9)

两个问题都没有。扩展方法实际上是一种方法,它将扩展操作的对象作为第一个参数。

new关键字用于为类的实例分配资源。扩展方法对实例进行操作,但不能作为新替换,只是因为它需要一个实例(或该类型的null)作为第一个参数。

考虑:

public static class StringExtensions
{
    public static string Reverse(this string _this)
    {
        // logic to reverse the string
    }
}

您可以通过两种方式调用此静态方法:

// as an extension method:
string s = "hello world";
string t = s.Reverse();

// as a static method invocation:
string t = StringExtensions.Reverse(s);

在任何一种情况下,编译器都会更改MSIL中的调用以映射第二个调用。编译之后,如果没有this - 关键字,你就无法识别它的静态对应的扩展方法。

总结

  • 扩展程序不是类的一部分
  • 扩展与继承无关,实际上它们是静态方法,不是继承的
  • 扩展无法实例化类似new关键字的类(但在方法内部,您当然可以实例化类)。
  • 扩展可以null上运行,否则该类的方法会引发NullReferenceException。这是因为实例只是静态方法中的第一个参数。
  • 可以扩展密封的类(如上面的string),这是通过继承无法实现的(不能从密封类派生)。

修改
Tigran和Floran暗示这个问题与new modifier有关,我补充说甚至可能是new generic constraint

扩展方法与new关键字的含义具有 no 关系。然而,这里有一些关于彼此的想法。我希望它不会让事情更加混乱。如果是这样,请坚持“编辑”上面的部分;)

  • 在新修饰符上:

    • new修饰符用于隐藏现有方法。扩展方法永远不会隐藏现有方法,因为声明是静态方法。当你这样做时,你甚至不会收到编译时警告或错误。
    • new修饰符要求方法(或属性)已存在且可访问。只有具有相同签名的方法 not 已存在时,扩展方法才能起作用。
    • new修饰符通过继承操作类的扩展,即每个方法都已被继承。扩展方法对类的实例进行操作,并且与类没有继承关系。
  • 关于新的通用约束:

    • 约束将允许的泛型类型限制为具有可访问的无参数构造函数的类型。扩展方法与泛型无关。
    • 扩展方法本身可以是通用的,并且参数(即它所操作的允许类)可以受到新通用约束的限制:

      // this ext. method will only operate on classes that inherit 
      // from ICollectible and have a public parameterless constructor
      public static int CalculateTotal<T>(this T _collectible)
          where T : ICollectible, new()
      {
          // calculate total
      }
      

答案 1 :(得分:3)

不,扩展方法只是扩展了现有类的功能。

  

扩展方法使您可以向现有类型“添加”方法   无需创建新的派生类型,重新编译或其他方式   修改原始类型。

请参阅MSDN on Extension Methods (C# Programming Guide)

需要使用new关键字来从基类中override非虚拟和静态方法。

public class A
{
   public virtual void One();
   public void Two();
}

public class B : A
{
   public override void One();
   public new void Two();
}

B b = new B();
A a = b as A;

a.One(); // Calls implementation in B
a.Two(); // Calls implementation in A
b.One(); // Calls implementation in B
b.Two(); // Calls implementation in B

查看this link on new vs override

答案 2 :(得分:1)

没有。扩展方法是一个单独的静态类的语法糖,它作为第一个参数,是一个被“扩展”的类型的对象。它与继承无关。该方法只能访问“扩展”类的公共成员,就像任何其他类一样。

答案 3 :(得分:0)

扩展方法与继承或new关键字(或构造函数)无关。如果您想为没有源代码的类添加一些功能,它们允许更好的代码。如果你有源代码,它也可以工作,但通常最好只更改源代码。

例如,您可能希望能够这样做:

string text = "this is my string";
int count = text.WordCount();

String类中不存在此方法,您需要这样做:

string text = "this is my string";
int count = MyCommon.WordCount(text);

其中WordCount()是某种常见库中的静态方法。

但是使用扩展方法,你也可以这样做:

public static class MyExtensions
{
    public static int WordCount(this String str)
    {
        return str.Split(new char[] { ' ', '.', '?' }, 
                         StringSplitOptions.RemoveEmptyEntries).Length;
    }
}

然后text.WordCount()将起作用,就像它是String类中定义的普通方法一样。它只是让事情变得更好用。

我建议您阅读here的代码。