Как расширить класс с помощью методов расширения С#?
Могут ли методы расширения применяться к классу?
Например, добавьте DateTime, чтобы включить метод Tomorrow(), который можно вызвать, например:
DateTime.Tomorrow();
Я знаю, что могу использовать
static DateTime Tomorrow(this Datetime value) { //... }
или
public static MyClass {
public static Tomorrow() { //... }
}
для аналогичного результата, но как я могу расширить DateTime, чтобы я мог вызывать DateTime.Tomorrow?
Ответы
Ответ 1
Вы не можете добавлять методы к существующему типу, если существующий тип не отмечен как частичный, вы можете добавлять только методы, которые, как представляется, являются членами существующего типа с помощью методов расширения. Поскольку это так, вы не можете добавлять статические методы к самому типу, так как в методах расширения используются экземпляры этого типа.
Ничего не мешает вам создать свой собственный статический вспомогательный метод, подобный этому:
static class DateTimeHelper
{
public static DateTime Tomorrow
{
get { return DateTime.Now.AddDays(1); }
}
}
Что вы будете использовать следующим образом:
DateTime tomorrow = DateTimeHelper.Tomorrow;
Ответ 2
Используйте метод расширения.
Пример:
namespace ExtensionMethods
{
public static class MyExtensionMethods
{
public static DateTime Tomorrow(this DateTime date)
{
return date.AddDays(1);
}
}
}
Использование:
DateTime.Now.Tomorrow();
или
AnyObjectOfTypeDateTime.Tomorrow();
Ответ 3
Методы расширения - это синтаксический сахар для создания статических методов, первым параметром которого является экземпляр типа T, как если бы он был методом экземпляра на T.
Таким образом, преимущество в значительной степени утрачивается, когда вы делаете "статические методы расширения", поскольку они будут путать читателя с кодом даже больше, чем метод расширения (поскольку они кажутся полностью квалифицированными, но на самом деле не определены в этот класс) без синтаксического усиления (возможность цепочки вызовов в свободном стиле в Linq, например).
Поскольку вам придется приносить расширения в область с использованием в любом случае, я бы сказал, что проще и безопаснее создавать:
public static class DateTimeUtils
{
public static DateTime Tomorrow { get { ... } }
}
И затем используйте это в своем коде через:
WriteLine("{0}", DateTimeUtils.Tomorrow)
Ответ 4
Ближе всего я могу ответить на вопрос, добавив метод расширения в объект System.Type
. Не очень, но все же интересно.
public static class Foo
{
public static void Bar()
{
var now = DateTime.Now;
var tomorrow = typeof(DateTime).Tomorrow();
}
public static DateTime Tomorrow(this System.Type type)
{
if (type == typeof(DateTime)) {
return DateTime.Now.AddDays(1);
} else {
throw new InvalidOperationException();
}
}
}
В противном случае IMO Andrew и ShuggyCoUk имеют лучшую реализацию.
Ответ 5
К сожалению, вы не можете этого сделать. Я считаю, что это было бы полезно. Естественно вводить:
DateTime.Tomorrow
чем:
DateTimeUtil.Tomorrow
С классом Util вы должны проверить наличие статического метода в двух разных классах, а не в одном.
Ответ 6
Я бы сделал то же самое, что и Kumu
namespace ExtensionMethods
{
public static class MyExtensionMethods
{
public static DateTime Tomorrow(this DateTime date)
{
return date.AddDays(1);
}
}
}
но назовите его как новый DateTime(). Tomorrow();
Думаю, что он делает больше, чем DateTime.Now.Tomorrow();
Ответ 7
Они предоставляют возможность расширения существующих типов путем добавления новых методов без каких-либо изменений, необходимых для этого типа. Методы вызова из объектов расширенного типа в приложении с использованием синтаксиса метода экземпляра известны как "расширяющие методы". Методы расширения не являются членами экземпляра типа.
Ключевым моментом для запоминания является то, что методы расширения, определенные как статические методы, находятся в области видимости только тогда, когда пространство имен явно импортировано в исходный код приложения с помощью директивы using. Несмотря на то, что методы расширения определяются как статические методы, они все еще вызываются с использованием синтаксиса экземпляра.
Посмотрите полный пример здесь
http://www.dotnetreaders.com/articles/Extension_methods_in_C-sharp.net,Methods_in_C_-sharp/201
Пример:
class Extension
{
static void Main(string[] args)
{
string s = "sudhakar";
Console.WriteLine(s.GetWordCount());
Console.ReadLine();
}
}
public static class MyMathExtension
{
public static int GetWordCount(this System.String mystring)
{
return mystring.Length;
}
}
Ответ 8
Я искал нечто похожее - список ограничений для классов, которые предоставляют методы расширения. Сложно найти краткий список, вот так:
-
У вас нет никаких личных или защищенных объектов - полей, методов и т.д.
-
Это должен быть статический класс, как в public static class...
.
-
В классе могут быть только методы, и все они должны быть общедоступными.
-
Вы не можете использовать обычные статические методы - те, которые не включают этот аргумент, не допускаются.
-
Все методы должны начинаться:
public static ReturnType Имя метода (this ClassName _this,...)
Таким образом, первым аргументом всегда является эта ссылка.
Существует неявная проблема, которую это создает - если вы добавляете методы, требующие блокировки любого типа, вы не можете реально предоставить ее на уровне класса. Как правило, вы предоставляете частную блокировку на уровне экземпляра, но невозможно добавить какие-либо частные поля, оставив вам некоторые очень неудобные параметры, например, предоставить ему публичный статический код в каком-либо внешнем классе и т.д. Получается рискованным. Знаки язык С# имел плохой поворот в дизайне для этих.
Обходной путь заключается в том, чтобы использовать ваш метод расширения как просто фасад для обычного класса, а все статические методы в вашем классе расширения просто называют реальный класс, возможно, используя a Singleton.
Ответ 9
Мы улучшили наш ответ с подробным объяснением. Теперь его легче понять о методе расширения
Метод расширения: это механизм, с помощью которого мы можем расширить поведение существующего класса, не используя подкласс, не изменяя или не перекомпилируя оригинальный класс или структура.
Мы можем расширить наши классы пользовательских классов .net и т.д.
Метод расширения - это особый тип статического метода, который определяется в статическом классе.
Поскольку класс DateTime
уже взят выше, и поэтому мы не взяли этот класс для объяснения.
Ниже приведен пример
//Это уже существующий класс калькулятора, который имеет только один метод (Add)
public class Calculator
{
public double Add(double num1, double num2)
{
return num1 + num2;
}
}
// Below is the extension class which have one extension method.
public static class Extension
{
// It is extension method and it first parameter is a calculator class.It behavior is going to extend.
public static double Division(this Calculator cal, double num1,double num2){
return num1 / num2;
}
}
// We have tested the extension method below.
class Program
{
static void Main(string[] args)
{
Calculator cal = new Calculator();
double add=cal.Add(10, 10);
// It is a extension method in Calculator class.
double add=cal.Division(100, 10)
}
}