Где я могу поместить мой метод расширения?
Старший член здесь дал мне этот код:
public static string Truncate(this string value, int maxChars)
{
return value.Length <= maxChars ? value : value.Substring(0, maxChars) + " ..";
}
Он сказал, чтобы использовать его как метод расширения. Но где я могу поместить этот метод? Похоже, что он добавляет что-то в .Net
Ответы
Ответ 1
Рассмотрим класс с именем 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);
Ответ 2
Поместите его в статический класс и используйте 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));
}
}
Ответ 3
Да, используйте статический класс. Я организовываю отдельный проект, который я могу использовать для решения. Я также организую отдельные файлы, сгруппированные по тому, что я расширяю, например, строки, перечисления, io, datetime и т.д.
Ответ 4
В дополнение к другим ответам: да, это своего рода расширение .NET. Более строго говоря, расширение уже скомпилированных классов. Вы можете "добавлять" методы к классам, которые недоступны для вашей модификации. С внутренней точки зрения это просто синтаксический сахар: ваши методы не могут быть замечены отражением. Но для пользователей вашего расширения кажется, что методы действительно добавлены в целевой класс (ну, с некоторыми отличиями).
Возможность влиять каким-то образом уже написанный код является неотъемлемой частью объектно-ориентированного подхода. Почти на любом языке OO вы можете получить какой-то существующий класс и добавить к нему некоторые функции (хотя это не является предпочтительным способом повторного использования кода). В Objective C вы можете изменять существующие классы, используя категории во время компиляции. В JavaScript вы можете изменять их даже во время выполнения, используя прототип.
Поскольку С# не является таким динамическим языком, как JavaScript, модификация существующих классов доступна в несколько ограниченной форме методов расширения.