Это синтаксис для объявления методов расширения, новой функции C # 3.0.
Метод расширения - это часть кода, часть "волшебства" компилятора, где компилятор с помощью intellisense в Visual Studio создает впечатление, что ваш метод расширения действительно доступен как метод экземпляра для рассматриваемого объекта.
Приведу пример.
В классе String нет метода с именем GobbleGobble, поэтому давайте создадим метод расширения:
public static class StringExtensions
{
public static void GobbleGobble(this string s)
{
Console.Out.WriteLine("Gobble Gobble, " + s);
}
}
Имя класса - это просто мое соглашение об именах, не обязательно называть его так, но оно должно быть статическим, как и метод.
После объявления вышеуказанного метода вы можете в Visual Studio ввести следующее:
String s = "Turkey Baster!";
s.
после точки дождитесь intellisense и обратите внимание, что там есть метод GobbleGobble, завершите код следующим образом:
String s = "Turkey Baster!";
s.GobbleGobble();
Важно : класс, в котором объявлен метод расширения, должен быть доступен компилятору и процессору intellisense, чтобы intellisense мог показать метод. Если вы вводите GobbleGobble вручную и используетеCtrl. сочетанием клавиш + , это не поможет вам получить права using в файле.
Обратите внимание, что параметр метода исчез. Компилятор будет незаметно перемещать важные биты, а именно:
String s = "Turkey Baster!";
s.GobbleGobble();
^ ^
| +-- the compiler will find this in the StringExtensions class
|
+-- will be used as the first parameter to the method
Таким образом, приведенный выше код будет преобразован компилятором в следующий:
String s = "Turkey Baster!";
StringExtensions.GobbleGobble(s);
Так что во время вызова в этом нет ничего волшебного, это просто вызов статического метода.
Обратите внимание, что если ваш метод расширения объявляет более одного параметра, только первый поддерживает this
модификатор, а остальные должны быть указаны как часть вызова метода как обычно:
public static void GobbleGobble(this string value, string extra)
{ | |
... | |
} | |
| |
+--------------------------------------------+ |
| |
v |
s.GobbleGobble("extra goes here"); |
^ |
| |
+-----------------------------------+
Методы расширения были добавлены частично из-за Linq, где синтаксис Linq C # будет искать методы расширения с соответствующими именами для объектов в игре, что означает, что вы можете «внедрить» поддержку Linq в любой тип класса, просто объявив правильное расширение. методы. Конечно, полная поддержка Linq - это большая работа, но это возможно.
Кроме того, сами по себе методы расширения действительно полезны, так что читайте об этом.
Вот несколько ссылок:
После методов расширения я использую их как сумасшедший ... вот несколько, которые я использую постоянно ...
public static T ChangeType<T>(this object obj) { return (T)Convert.ChangeType(obj, typeof(T)); }
Работает вот так ..
int i = "123".ChangeType<int>(); bool valid = "bool".ChangeType<bool>(); int id = dataSet.Tables[0].Rows[0]["Id"].ChangeType<int>();
Да, это проявляется на каждом отдельном объекте, может раздражать, но поскольку я использую это практически для каждого типа данных, это помогает просто прикрепить его к объекту, а не дублировать его для каждого возможного типа данных.
public static string ToXml(this object serializableObject) { var aMemStr = new MemoryStream(); try { var serializer = new XmlSerializer(serializableObject.GetType()); serializer.Serialize(new XmlTextWriter(aMemStr, null), serializableObject); return Encoding.UTF8.GetString(aMemStr.ToArray()); } finally { if (aMemStr != null) { aMemStr.Dispose(); } } } string xml = dataSet.ToXml(); public static T ToObject<T>(this string xmlString) { var aStream = new MemoryStream(Encoding.UTF8.GetBytes(xmlString)); try { return (T)new XmlSerializer(typeof(T)).Deserialize(aStream); } finally { if (aStream != null) { aStream.Dispose(); aStream = null; } } } DataSet dataSet = xml.ToObject<DataSet>();
источник
Он используется для методов расширения. По сути, вы «приклеиваете» Helpername к объекту htmlHelper, чтобы вы могли сказать:
new HtmlHelper().HelperName(...more regular params);
источник
Это был бы метод расширения. Они позволяют «расширять» класс с помощью статических методов, находящихся за пределами исходного класса.
Например, скажем, у вас есть полезный строковый метод, который вы используете все время ...
public int CountAllAs(string orig) { return orig.ToLowerInvariant().ToArray().Count(c => c == 'a'); }
И вы называете это ...
string allAs = "aaaA"; int count = CountAllAs(allAs);
Это не так уж и плохо. Но с небольшим изменением вы можете сделать его методом расширения, и вызов будет немного красивее:
public static int CountAllAs(this string orig) { return orig.ToLowerInvariant().ToArray().Count(c => c == 'a'); }
А потом назовите это ...
string allAs = "aaaA"; int count = allAs.CountAllAs();
источник
Методы расширений ...
... это фантастический способ включить функциональность, например, если вы используете шаблон декоратора , но без боли рефакторинга всего вашего кода или использования другого имени общего типа.
public static class Extensions { public static string RemoveComma(this string value) { if (value == null) throw new ArgumentNullException("value"); return value.Replace(",", ""); } }
Таким образом, вы можете использовать этот код в любом месте вашего приложения.
Таким образом, атрибут команды this означает тип, к которому будет «добавлено» расширение, и позволяет работать со значением, как если бы оно было передано как параметр.
источник