Можете ли вы добавить статические расширения для классов в C #? Нет, но вы можете сделать это:
public static class Extensions
{
public static T Create<T>(this T @this)
where T : class, new()
{
return Utility<T>.Create();
}
}
public static class Utility<T>
where T : class, new()
{
static Utility()
{
Create = Expression.Lambda<Func<T>>(Expression.New(typeof(T).GetConstructor(Type.EmptyTypes))).Compile();
}
public static Func<T> Create { get; private set; }
}
Вот как это работает. Хотя технически вы не можете написать статические методы расширения, вместо этого этот код использует лазейку в методах расширения. Эта лазейка заключается в том, что вы можете вызывать методы расширения для нулевых объектов, не получая нулевое исключение (если вы не обращаетесь к чему-либо через @this).
Итак, вот как вы могли бы использовать это:
var ds1 = (null as DataSet).Create(); // as oppose to DataSet.Create()
// or
DataSet ds2 = null;
ds2 = ds2.Create();
// using some of the techniques above you could have this:
(null as Console).WriteBlueLine(...); // as oppose to Console.WriteBlueLine(...)
Теперь, ПОЧЕМУ я выбрал вызов конструктора по умолчанию в качестве примера, и почему я просто не могу вернуть new T () в первом фрагменте кода, не выполняя весь этот мусор Expression? Ну, сегодня ваш счастливый день, потому что вы получаете 2fer. Как знает любой продвинутый разработчик .NET, new T () работает медленно, поскольку генерирует вызов System.Activator, который использует отражение, чтобы получить конструктор по умолчанию перед вызовом. Черт бы тебя побрал, Microsoft! Однако мой код вызывает конструктор объекта по умолчанию напрямую.
Статические расширения были бы лучше, чем это, но отчаянные времена требуют отчаянных мер.