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

例如,如果我想添加一个名为“WriteBlueLine”的扩展到控制台,这样我就可以:

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

我尝试通过添加一个本地的公共静态方法,并将Console作为“this”参数…但是不行!

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

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


当前回答

这是不可能的。

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

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

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

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

如果决定允许实例的扩展,我认为没有任何逻辑理由不允许静态扩展。一旦实例可以扩展,关于分段库的争论就站不住脚了。

其他回答

以下内容作为对tvanfosson回答的编辑被拒绝。我被要求把它作为我自己的答案。我使用了他的建议并完成了ConfigurationManager包装器的实现。原则上我只是填了…在tvanfosson的回答中。

不。扩展方法需要对象的实例。你可以 但是,在ConfigurationManager周围编写一个静态包装器 接口。如果实现了包装器,就不需要扩展 方法,因为您可以直接添加方法。

public static class ConfigurationManagerWrapper
{
    public static NameValueCollection AppSettings
    {
        get { return ConfigurationManager.AppSettings; }
    }

    public static ConnectionStringSettingsCollection ConnectionStrings
    {
        get { return ConfigurationManager.ConnectionStrings; }
    }

    public static object GetSection(string sectionName)
    {
        return ConfigurationManager.GetSection(sectionName);
    }

    public static Configuration OpenExeConfiguration(string exePath)
    {
        return ConfigurationManager.OpenExeConfiguration(exePath);
    }

    public static Configuration OpenMachineConfiguration()
    {
        return ConfigurationManager.OpenMachineConfiguration();
    }

    public static Configuration OpenMappedExeConfiguration(ExeConfigurationFileMap fileMap, ConfigurationUserLevel userLevel)
    {
        return ConfigurationManager.OpenMappedExeConfiguration(fileMap, userLevel);
    }

    public static Configuration OpenMappedMachineConfiguration(ConfigurationFileMap fileMap)
    {
        return ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
    }

    public static void RefreshSection(string sectionName)
    {
        ConfigurationManager.RefreshSection(sectionName);
    }
}

我在试图找到OP同样问题的答案时偶然发现了这条线索。我没有找到我想要的答案,但我最后做了这个。

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

我是这样用的:

ConsoleColor.Cyan.WriteLine("voilà");

不能向类型添加静态方法。只能向某个类型的实例添加(伪)实例方法。

this修饰符的作用是告诉c#编译器将实例传递到。作为静态/扩展方法的第一个参数。

在向类型添加静态方法的情况下,没有为第一个参数传递实例。

我试着用系统来做这件事。当时我正在学习扩展方法,但没有成功。正如其他人提到的,原因是扩展方法需要类的实例。

从c# 7开始,这是不支持的。然而,关于在c# 8中集成这样的东西的讨论和建议值得支持。