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

Rup*_*pal 3 .net c# inheritance extension-methods new-operator

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

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

Abe*_*bel 9

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

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

考虑:

public static class StringExtensions
{
    public static string Reverse(this string _this)
    {
        // logic to reverse the string
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

// as a static method invocation:
string t = StringExtensions.Reverse(s);
Run Code Online (Sandbox Code Playgroud)

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

总结一下

  • 扩展不是课程的一部分
  • 扩展与继承无关,实际上它们是静态方法,不是继承的
  • 扩展不能new关键字那样实例化类(但在方法中你当然可以实例化类).
  • 扩展可以操作null,否则该类的方法将引发a NullReferenceException.这是因为实例只是静态方法中的第一个参数.
  • 可以扩展密封类(string如上所述),这是通过继承无法实现的(不能从密封类派生).

编辑:
Tigran和Floran暗示这个问题是关于新的修饰符,我补充说它甚至可能是关于新的通用约束.

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

  • 在新修饰符上:

    • new修饰符用于隐藏现有方法.扩展方法永远不能隐藏现有方法,因为声明是静态方法.当你这样做时,你甚至不会得到编译时警告或错误.
    • new修饰符要求方法(或属性)已存在且可访问.如果具有相同签名的方法也扩展方法才能发挥作用存在.
    • 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
      }
      
      Run Code Online (Sandbox Code Playgroud)

  • 我相信这个问题是关于[new modifier](http://msdn.microsoft.com/en-us/library/51y09td4%28v=vs.71%29.aspx#vclrfnew_newmodifier),就像在habib.osu中一样回复,而不是[新运算符](http://msdn.microsoft.com/en-us/library/51y09td4%28v=vs.71%29.aspx#vclrfnew_newoperator).除此之外,我同意你的回复. (3认同)