IRONSOFTWAREHOME

理解方法和使用 C# 扩展方法

理解 C# 变量和数据类型

Tim Corey

28m 27s

在 C# 编程中,方法是重要的构建模块,用于封装可重用代码并执行特定任务。 它们可以接受参数、返回值,并且可以被重载以处理不同的输入。 扩展方法是一种更高级的概念,它允许开发人员向现有类型(包括他们无法控制的类型)添加功能。

Tim Corey的视频"如何在 C# 中创建扩展方法"是一个非常好的资源。 在本指南中,我们将探讨蒂姆涉及的几个主题:

  1. 定义和调用方法
  2. 方法参数和参数
  3. 方法返回值
  4. 方法重载
  5. 实现扩展方法

定义和调用方法

已定义实例方法

在 C# 中,方法是在类中定义的。 方法定义的通用语法包括访问修饰符、返回类型、方法名称和参数。

public class SampleClass
{
    public void SampleMethod()
    {
        // Method implementation  
    }
}

在 Tim Corey 4 分 05 秒的示例中,他定义了一个静态类中的方法来创建一个扩展方法。 定义的方法是PrintToConsole。 该定义包含了所有通用语法,并通过一个实际示例清楚地解释了如何定义方法:

public static class Extensions
{
    public static void PrintToConsole(this string message)
    {
        Console.WriteLine(message);
    }
}

调用方法

"方法调用"告诉程序执行代码中其他地方定义的特定方法,从而执行预定义的操作。 方法可以通过类实例调用,如果是静态方法,则可以直接调用。 对于扩展方法,它们看起来就像是它们所扩展的类型的一部分。 在视频 6 分 18 秒处,Tim 展示了如何像调用预定义方法一样,使用原始数据类型调用扩展方法。

string demo = "This is a demo";
demo.PrintToConsole(); // Extension method call

方法参数和实参

参数

参数在方法定义中指定,并作为传递给方法的值的占位符。 在调用message

public void DisplayMessage(string message)
{
    Console.WriteLine(message);
}

再次,在Tim Corey于4:05给出的扩展方法示例中,message是参数:

public static void PrintToConsole(this string message)
{
    Console.WriteLine(message);
}

论点

参数是调用方法时传递给该方法的实际值。

DisplayMessage("Hello, World!"); // "Hello, World!" is the argument

当Tim Corey在6:20通过点语法调用字符串类型的方法时,字符串值实际上被作为一个值传递给PrintToConsole方法:

string demo = "This is a demo";
demo.PrintToConsole(); // "This is a demo" is the argument

方法返回值

方法可以使用 return 语句返回值。 返回类型在方法签名中指定。

public int Add(int a, int b)
{
    return a + b;
}

虽然 Tim Corey 视频中的扩展方法不返回值(void 返回类型),但您可以创建带有返回值的扩展方法。 Tim 的示例中返回类型为 void,这意味着该方法不返回任何值。 以下示例展示了如何返回一个值:

public static int WordCount(this string str)
{
    return str.Split(' ').Length;
}

方法重载(11:15)

方法重载允许多个方法具有相同的名称但参数不同。 这有助于创建灵活直观的API。

public void Display(string message)
{
    Console.WriteLine(message);
}

public void Display(int number)
{
    Console.WriteLine(number);
}

Tim Corey 在 11:24 简要地谈到了为不同的日志记录场景创建多个方法,这可以看作是更广泛意义上的方法重载的一个例子。 log 方法有两个版本,一个版本有一个参数,另一个版本有两个参数。 11:39 处的第二个日志方法是日志方法的重载版本,它以相同的名称提供了多种功能。

Implementing Extension Methods in C#

什么是扩展方法? (3:13)

扩展方法允许你向现有类型添加新方法,而无需修改或重新编译它们。 虽然它们被称作实例方法,但扩展方法被定义为静态方法。

创建扩展方法

在上一节"定义和调用方法"中,我们重点介绍了 Tim Corey 如何在单独的静态类中创建扩展方法,并在其中定义静态方法以用作扩展方法。 以下是蒂姆·科里强调的一些关键点:

  1. 务必定义一个单独的公共静态类,或者,正如 Tim 所说,"将类标记为静态,否则它将无法工作。"
  2. 创建更多扩展方法时,请按类型对它们进行分组 (3:43)
  3. 定义一个静态方法,并在第一个参数前加上this关键字,指定要扩展的类型(4:58)
public static class Extensions
{
    public static void PrintToConsole(this string message)
    {
        Console.WriteLine(message);
    }
}

调用扩展方法(6:18)

接下来,Tim 将演示如何对该字符串变量调用扩展方法:

demo.PrintToConsole();

当您输入PrintToConsole方法。 这是新添加到string类型的方法。

方法调用的工作原理(6:30)

Tim解释了为什么您可以调用demo.PrintToConsole()

  • 演示是字符串类型:变量string类型。
  • 扩展的字符串类型PrintToConsole进行扩展。

理解参数(6:41)

虽然似乎没有参数传递给PrintToConsole方法,Tim指出了隐式参数传递 - demo字符串作为第一个参数传递给扩展方法。

Tim 强调,扩展方法在调用时比其定义中少一个参数。 这是因为第一个参数(被扩展的类型)是隐式的。

扩展方法签名

这里,message是隐式参数:

public static void PrintToConsole(this string message)

运行代码(7:08)

最后,当PrintToConsole方法被调用时,它将字符串输出到控制台:

Console.WriteLine(message);

因此,调用demo.PrintToConsole()会在控制台打印"这是一个演示"。

使用第三方类的扩展方法

扩展第三方类(10:59)

Tim Corey解释说,扩展方法可以扩展任何类型,甚至是您无法直接修改的第三方类。 例如,让我们看一下11:09的SimpleLogger类。

这里,Tim使用了一个假设的第三方类SimpleLogger,该类将消息记录到控制台(11:09)。 该类有两个方法:

public class SimpleLogger
{
    public void Log(string message)
    {
        Console.WriteLine(message);
    }

    public void Log(string message, string messageType)
    {
        Console.WriteLine($"{messageType}: {message}");
    }
}

这些方法并不理想,因为消息类型是简单的字符串,这可能会导致不一致。 Tim建议创建扩展方法来改进该类。

实现一致的消息类型

使用扩展方法可以确保代码的一致性,始终使用相同的消息类型和格式。 在12:40这里,Tim创建了一个静态类ExtendSimpleLogger

public static class ExtendSimpleLogger
{
    public static void LogError(this SimpleLogger logger, string message)
    {
        logger.Log(message, "Error");
    }
   
    public static void LogWarning(this SimpleLogger logger, string message)
    {
        logger.Log(message, "Warning");
    }
}

使通话更加一致

通过此操作(14:02),他现在可以在SimpleLogger实例上调用扩展方法:

SimpleLogger logger = new SimpleLogger();
logger.LogError("This is an error");
logger.LogWarning("This is a warning");

这样可以确保消息类型始终为"错误"和"警告"。

增强输出格式(14:35)

Tim 添加了设置错误信息控制台文本颜色的功能,确保错误信息更加醒目:

public static void LogError(this SimpleLogger logger, string message)
{
    var defaultColor = Console.ForegroundColor;
    Console.ForegroundColor = ConsoleColor.Red;
    logger.Log(message, "Error");

    Console.ForegroundColor = defaultColor;
}

与直接方法调用比较(17:21)

Tim将这种方法与直接调用原始Log方法进行了比较,这可能导致不一致:

logger.Log("Test error", "Error");
logger.Log("Another error", "ERROR");

这种方法容易出现拼写错误和格式不一致的问题。

链式扩展方法(18:13)

Tim演示了如何将扩展方法链接起来,使代码更易读:

public static void LogInfo(this SimpleLogger logger, string message)
{
    logger.Log(message, "Info");
}

public static void SaveToDatabase(this SimpleLogger logger)
{
    // Simulate saving to a database
}

现在,您可以将这些方法串联起来使用:

logger.LogInfo("Information").SaveToDatabase();

与嵌套方法调用相比,这使得代码更易读、更直观:

SaveToDatabase(LogInfo(logger, "Information"));

通过使用点表示法和链式调用,代码的意图更加清晰,嵌套也更少。

延长你不拥有的物品的使用期限

20:13,Tim Corey 解释说,扩展方法非常适合向你不拥有的类(例如第三方库)添加功能。 这样可以在不修改原始代码的情况下进行增强。

避免依赖

Corey 还强调了使用扩展方法来引入依赖项,而无需将它们直接耦合到类中。 例如,在不嵌入数据库逻辑的情况下,将数据库保存功能添加到Person类中。

扩展接口

扩展方法也可以应用于接口,如 21:30 所述,它允许实现该接口的多个类共享相同的功能。 这有助于代码重用和简化。

何时不应使用扩展方法

23:03,Tim Corey 建议不要过度使用扩展方法,尤其是对于原始类型或 Microsoft 提供的类型,以防止代码混乱和复杂化。 谨慎使用,且仅在能带来明显好处时才使用。

开放/封闭原则

在 24:54-25:40 这段中,Tim 强调要遵循开闭原则,使用扩展方法添加新功能,而无需修改现有的稳定代码,从而降低引入错误的风险。

使用语句的最佳实践

将扩展方法按逻辑分组,并放置在单独的命名空间中,以避免命名冲突,并方便维护和调试。

结论

至此,您就了解了定义和调用方法、处理参数和返回值以及利用方法重载的基本知识。 这样一来,你就可以用 C# 构建强大而灵活的应用程序了。

正如 Tim Corey 所解释的那样,扩展方法提供了一种强大的方法来增强现有类型,并使你的代码更易读、更易维护。 如需更详细的见解和实际示例,您可以观看 Tim Corey 关于如何在 C# 中创建扩展方法的完整视频。

Earn More by Sharing What You Love

Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!

Let's Stay in Touch!

Join our newsletter, you’ll get exclusive access on article updates. We value your privacy

Key in blue circle

立即获取免费的 30 天试用版密钥

Your trial license will be sent to your email address

无任何限制。100% 解锁。无需信用卡。

OR
bullet_checked无需信用卡或创建账户无任何限制。100% 解锁。无需信用卡。
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried Iron Suite
获取您的无义务咨询
填写下面的表格或通过sales@ironsoftware.com
您的资料将始终保密。
深受全球数百万工程师信赖
Iron Software 的客户徽标
立即获取您的免费30 天试用密钥
无需信用卡或创建账户