Где я могу разместить свой метод расширения? - PullRequest
25 голосов
/ 17 июля 2011

Старший член дал мне этот код:

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

Он сказал использовать его как метод расширения.Но куда мне положить этот метод?Похоже, что-то добавляет .Net

Ответы [ 4 ]

38 голосов
/ 17 июля 2011

Рассмотрим класс с именем 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);
        }
    }
}

Кстати, вы не добавляете его в.СЕТЬ.Вы даже не добавляете новый метод в класс String.Скорее, это трюк компилятора, который заставляет статические методы жить в статических классах с их первым параметром, объявленным как this *TypeName* *valueParameter*, где *TypeName* - это имя типа, а *valueParameter* - это имя параметра, которое может быть отображено какметод экземпляра для экземпляров типа с именем типа *TypeName*.То есть

string t = s.Truncate(5);

переводится компилятором в

string t = StringExtensions.Truncate(s, 5);
2 голосов
/ 17 июля 2011

Поместите его в статический класс и используйте 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));
    }
}
0 голосов
/ 17 июля 2011

В дополнение к другим ответам: да, это своего рода расширение .NET.Строго говоря, расширение уже скомпилированных классов.Вы можете «добавлять» методы в классы, которые недоступны для вашей модификации.С внутренней точки зрения, это просто синтаксический сахар: ваши методы не могут быть отражены отражением.Но для пользователей вашего расширения это выглядит так, как будто методы действительно добавлены в целевой класс (ну, с некоторыми отличиями).

Возможность каким-либо образом повлиять на уже написанный кодсущественная часть объектно-ориентированного подхода.Почти в любом языке OO вы можете получить из некоторый существующий класс и добавить некоторые функциональные возможности таким образом (хотя это не предпочтительный способ повторного использования кода).В Objective C вы можете изменить существующие классы, используя category во время компиляции.В JavaScript вы можете изменять их даже во время выполнения, используя prototype .

Поскольку C # не такой динамический язык, как JavaScript, изменение существующих классов доступно в несколько ограниченной форме.методы расширения.

0 голосов
/ 17 июля 2011

Да, используйте статический класс. Я организую в отдельный проект, который я могу использовать в разных решениях. Я также объединяюсь в отдельные файлы, сгруппированные по расширениям, таким как строки, перечисления, io, datetime и т. Д.

...