我可以将扩展方法添加到现有的静态类吗?

我是C#中扩展方法的粉丝,但是还没有成功将扩展方法添加到静态类(如Console)。

例如,如果我想向控制台添加一个名为'WriteBlueLine'的扩展,以便我可以:

Console.WriteBlueLine("This text is blue");

我试图通过添加一个本地的公共静态方法,作为一个'这个'参数的控制台...但没有骰子!

public static class Helpers {
    public static void WriteBlueLine(this Console c, string text)
    {
        Console.ForegroundColor = ConsoleColor.Blue;
        Console.WriteLine(text);
        Console.ResetColor();
    }
}

这没有添加'WriteBlueLine'方法到控制台...我做错了吗? 或者要求不可能的?


不需要。扩展方法需要一个对象的实例变量(值)。 但是,您可以在ConfigurationManager界面上编写一个静态包装器。 如果你实现了包装器,你不需要扩展方法,因为你可以直接添加方法。

 public static class ConfigurationManagerWrapper
 {
      public static ConfigurationSection GetSection( string name )
      {
         return ConfigurationManager.GetSection( name );
      }

      .....

      public static ConfigurationSection GetWidgetSection()
      {
          return GetSection( "widgets" );
      }
 }

你可以添加静态扩展到C#中的类吗? 不,但你可以这样做:

public static class Extensions
{
    public static T Create<T>(this T @this)
        where T : class, new()
    {
        return Utility<T>.Create();
    }
}

public static class Utility<T>
    where T : class, new()
{
    static Utility()
    {
        Create = Expression.Lambda<Func<T>>(Expression.New(typeof(T).GetConstructor(Type.EmptyTypes))).Compile();
    }
    public static Func<T> Create { get; private set; }
}

这是它的工作原理。 虽然技术上不能编写静态扩展方法,但是此代码会利用扩展方法中的漏洞。 这个漏洞是你可以在没有得到null异常的情况下调用null对象的扩展方法(除非你通过@this访问任何内容)。

所以这里是你将如何使用这个:

    var ds1 = (null as DataSet).Create(); // as oppose to DataSet.Create()
    // or
    DataSet ds2 = null;
    ds2 = ds2.Create();

    // using some of the techniques above you could have this:
    (null as Console).WriteBlueLine(...); // as oppose to Console.WriteBlueLine(...)

现在为什么我选择调用默认构造函数作为示例,并且为什么不在第一个代码片段中返回新的T()而没有执行所有表达式垃圾? 今天你的幸运日,因为你得到了2fer。 正如任何高级的.NET开发人员所知,新的T()很慢,因为它会调用System.Activator,它在调用它之前使用反射来获取默认构造函数。 该死的你微软! 然而,我的代码直接调用对象的默认构造函数。

静态扩展会比这更好,但绝望的时候需要绝望的措施。


这是不可能的。

是的,我认为MS在这里犯了一个错误。

他们的决定没有意义,并迫使程序员写(如上所述)一个毫无意义的包装类。

下面是一个很好的例子:试图扩展静态MS单元测试类Assert:我想要多一个Assert方法AreEqual(x1,x2)

做到这一点的唯一方法是指向不同的类或者围绕几百个不同的Assert方法编写一个包装器。 为什么!?

如果决定允许扩展实例,我认为没有理由不允许静态扩展。 一旦实例可以被扩展,关于切片库的观点就不会成立。

链接地址: http://www.djcxy.com/p/17443.html

上一篇: Can I add extension methods to an existing static class?

下一篇: evaluating cost/benefits of using extension methods in C# => 3.0