我把扩展方法放在哪里

本文关键字:在哪里 方法 扩展 | 更新日期: 2023-09-27 18:02:15

这里的一位资深成员给了我这样的代码:

public static string Truncate(this string value, int maxChars)
{
    return value.Length <= maxChars ? value : value.Substring(0, maxChars) + " ..";
}

他说用它作为一种扩展方法。但是我把这个方法放在哪里呢?它看起来像是给。net增加了一些东西

我把扩展方法放在哪里

考虑一个名为StringExtensions的类,如下所示:

static class StringExtensions
{
    public static string Truncate(this string value, int maxChars)
    {
        return value.Length <= maxChars ? 
               value : 
               value.Substring(0, maxChars) + " ..";
    }
}

无论你把这个类放在哪个命名空间,你都要为这个命名空间包含一个using声明。

因此,对于一个完整的例子:

StringExtensions.cs:

namespace My.Extensions
{
    static class StringExtensions
    {
        public static string Truncate(this string value, int maxChars)
        {       
            return value.Length <= maxChars ?
                   value :
                   value.Substring(0, maxChars) + " ..";
        }
    }
}

Program.cs:

using System;
using My.Extensions;
namespace My.Program
{
    static class Program
    {
        static void Main(string[] args)
        {
            string s = "Hello, World";
            string t = s.Truncate(5);
            Console.WriteLine(s);
            Console.WriteLine(t);
        }
    }
}
顺便说一下,你不能把它添加到。net。您甚至没有向类String添加新方法。相反,这是一个编译器的技巧,它使静态方法存在于静态类中,它们的第一个参数声明为this *TypeName* *valueParameter*,其中*TypeName*是类型的名称,*valueParameter*是参数的名称,可以在类型名称为*TypeName*的类型的实例上作为实例方法出现。这是
string t = s.Truncate(5);

被编译器翻译成

string t = StringExtensions.Truncate(s, 5);

将其放在静态类中,并在其命名空间上使用 using

namespace Foo
{
    static class Extensions
    {
        public static string Truncate(this string value, int maxChars)
        {
            return value.Length <= maxChars ?
                value : value.Substring(0, maxChars) + " ..";
        }
    }
}

然后在另一个文件:

using Foo;  //Don't forget this!
class Tester
{
    static void Test()
    {
        Console.WriteLine("123456".Truncate(3));
    }
}

是的,使用静态类。我在一个可以跨解决方案使用的单独项目中进行组织。我还根据我要扩展的内容(如字符串、枚举、io、datetime等)在单独的文件中进行组织

除了其他答案:是的,它是一种扩展。net。更严格地说,扩展已经编译的类。你可以在类中"添加"不能修改的方法。从内部的角度来看,它只是一个语法糖:您的方法无法通过反射看到。但是对于您的扩展的用户来说,看起来好像这些方法确实被添加到目标类中(好吧,有一些区别)。

以某种方式影响已经编写的代码的可能性是面向对象方法的重要组成部分。在几乎所有的OO语言中,您都可以从派生一些现有的类,并以这种方式为其添加一些功能(尽管这不是代码重用的首选方式)。在Objective C中,您可以在编译时使用类别修改现有的类。在JavaScript中,你甚至可以在运行时修改它们,使用prototype

由于c#不像JavaScript那样是一种动态语言,所以修改现有的类只能通过一些有限的扩展方法来实现。