扩展静态方法和非扩展静态方法在使用上有什么区别?

3

A类 中我有一个方法:

  public static String GetTimestamp(this DateTime value) {
            return value.ToString("yyyyMMddHHmmssffff");
        }

我称之为:

        String timeStamp = GetTimestamp(new DateTime());

如果该方法看起来像下面这样,使用上有什么区别吗?
  public static String GetTimestamp( DateTime value) {
                return value.ToString("yyyyMMddHHmmssffff");
            }

我从来没有见过像那样使用扩展方法。通常我会看到像 date.GetTimestamp(); 这样的用法,或者类似的方式,但两种方式都是可以接受的。 - pcnThird
4个回答

4
扩展方法的作用是让你可以这样调用它:
```C# 对象.扩展方法() ```
String timeStamp = new DateTime().GetTimestamp();

意思相同。这是唯一的变化。


我原本以为是这样,但它并没有起作用:“System.... DateTime()”不包含定义……这就是我得到的结果。 - Yoda
我明白了:错误1:扩展方法必须在非泛型静态类中定义 C:\Users\R\documents\visual studio 2013\Projects\HomeSecurity\HomeSecurity\VideoStream.cs 12 26 HomeSecurity - Yoda
1
你的类是static吗?你需要一个static class Something { ... }来扩展方法。 - Ry-
在C#中,如果我将类设为静态,它会有什么缺点吗? - Yoda
1
不要只是将包含类设为静态或其他什么的。创建一个新类。 - Ry-
显示剩余3条评论

2

扩展方法旨在被用作其目标类型的“似乎是”常规实例方法:

var timeStamp = new DateTime().GetTimestamp();

除此之外,没有任何区别。


C# 3.0引入了它们,以创建我们今天通常在LINQ中看到的美丽语法,例如:

  var soldProducts = customers.Where(x => x.IsActive)
                              .SelectMany(x => x.Orders)
                              .Where(x => x.Status == OrderStatus.Completed)
                              .Select(x => x.Product)
                              .ToList;

没有扩展方法,这个语法将不可能实现,并且需要很多常规的方法调用:

var activecustomers = Enumerable.Where(customers, x => x.IsActive);
var orders = Enumerable.SelectMany(activecustomers, x => x.Orders);
var completed = Enumerable.Where(orders, x => x.Status == OrderStatus.Completed);
var products = Enumerable.Select(completed, x => x.Product);
var soldProducts = Enumerable.ToList(products);

更不用说,类型推断在这里也扮演了重要角色,因为System.Linq.Enumerable中的大多数方法实际上都是具有一个或多个类型参数的通用方法,但C#编译器足够聪明,可以推断出通用类型参数并消除需要显式指定它们的需求。


2

扩展方法允许您将其视为问题类型内部的方法。因此,在您的第一个示例中,该方法可以被视为在 DateTime 类型内部的方法。因此,您可以执行以下操作:

var foo = new DateTime();
var timestamp = foo.GetTimestamp();

2
使用扩展方法版本,您也可以使用以下方式调用:
dateTime.GetTimeStamp()

如果您已经包含了它所声明的命名空间,那么就可以使用它。

好的,如何包含该命名空间? - Yoda
如果类A在命名空间MyNamespace中定义,那么在你尝试使用扩展时,在代码中只需添加using MyNamespace即可。 - Federico Berasategui
我正在使用这个扩展,就在它定义的地方下面。VS2013告诉我DateTime没有GetTimeStamp的定义。 - Yoda
好的,我明白:错误1:扩展方法必须在非泛型静态类中定义 C:\ Users \ R \ documents \ visual studio 2013 \ Projects \ HomeSecurity \ HomeSecurity \ VideoStream.cs 12 26 HomeSecurity - Yoda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接