Вопрос

Есть ли у C # свойства расширения?

Например, могу ли я добавить свойство расширения к DateTimeFormatInfo вызванный ShortDateLongTimeFormat который вернул бы ShortDatePattern + " " + LongTimePattern?

Это было полезно?

Решение

Нет, они не существуют в C # 3.0 и не будут добавлены в 4.0. Он находится в списке желаний для C #, поэтому он может быть добавлен в будущем.

На данный момент лучшее, что вы можете сделать, - это методы расширения стиля GetXXX.

Другие советы

Нет, их не существует.

Я знаю, что команда C # рассматривала их в какой-то момент (или, по крайней мере, Эрик Липперт рассматривал) - наряду с конструкторами расширений и операторами (это может занять некоторое время, чтобы вы пришли в себя, но это круто ...) Однако я не видел никаких доказательств того, что они станут частью C # 4.

Редактировать:Они не появились в C # 5, и по состоянию на июль 2014 года не похоже, что это появится и в C # 6.

Эрик Липперт, главный разработчик команды компиляторов C # в Microsoft до ноября 2012 года, написал об этом в блоге в октябре 2009 года:

На данный момент он все еще не поддерживается компилятором Roslyn ...

До настоящего времени свойства расширения не рассматривались как достаточно ценные, чтобы их можно было включить в предыдущие версии стандарта C #. C # 7 и C # 8.0 считают это чемпионом предложения, но оно еще не было выпущено, прежде всего потому, что даже если реализация уже существует, они хотят ее реализовать с самого начала.

Но это будет ...

В < есть элемент участники расширения . strong> рабочий список C # 7 , поэтому он может быть поддержан в ближайшем будущем. , Текущее состояние свойства расширения можно найти на Github под соответствующим элементом .

Однако есть еще более многообещающая тема: " расширить все " с особым вниманием к свойствам и статическим классам или даже полям.

Кроме того, вы можете использовать обходной путь

Как указано в этой статье , вы можете использовать Возможность TypeDescriptor прикреплять атрибут к экземпляру объекта во время выполнения. Однако он не использует синтаксис стандартных свойств.
Это немного отличается от простого синтаксического сахара, добавляющего возможность определять расширенное свойство, такое как
string Data (этот экземпляр MyClass) в качестве псевдонима для метода расширения
string GetData ( этот экземпляр MyClass) , поскольку он сохраняет данные в классе.

Я надеюсь, что C # 7 предоставит полнофункциональное расширение для всего (свойства и поля), однако на данный момент только время покажет.

И не стесняйтесь вносить свой вклад, поскольку программное обеспечение завтрашнего дня придет от сообщества.

Обновление: август 2016 года

Как опубликовала команда dotnet что нового в C # 7.0 и из комментария Мадса Торгенсена :

  

Свойства расширения: у нас был (блестящий!) стажер, реализовавший их поверх   лето как эксперимент, наряду с другими видами продления   члены. Мы по-прежнему заинтересованы в этом, но это большое изменение, и мы   нужно быть уверенным, что оно того стоит.

Кажется, что свойства расширения и другие члены все еще являются хорошими кандидатами для включения в будущий выпуск Roslyn, но, возможно, не в 7.0.

Обновление: май 2017 года

Участники расширения закрыты как дубликат проблема расширения , которая также закрыта. Основное обсуждение было на самом деле о расширяемости типов в широком смысле. Эта функция теперь отслеживается здесь как предложение и была удалено из 7.0 этап .

Обновление: август 2017 г. - предложенная функция в C # 8.0

Хотя он все еще остается только предложенной функцией, теперь у нас есть более четкое представление о том, каким будет его синтаксис. Имейте в виду, что это будет

Обновление (спасибо @chaost за указание на это обновление):

  

Мэдс Торгерсен: " Расширение всего не смогло сделать это в C # 8.0. Он был «пойман», если хотите, в очень захватывающей дискуссии о дальнейшем будущем языка, и теперь мы хотим убедиться, что мы не добавим его таким образом, который мешает этим будущие возможности. Иногда языковой дизайн - это очень длинная игра! & Quot;

Источник: раздел комментариев в https://blogs.msdn.microsoft.com/dotnet/2018/11/12/building-c-8-0/

<Ч>

Я перестал считать, сколько раз за эти годы я открыл этот вопрос в надежде увидеть, как это реализовано.

Ну, наконец-то мы все можем порадоваться! Microsoft собирается представить это в своем следующем выпуске C # 8.

Так что вместо этого ...

public static class IntExtensions
{
   public static bool Even(this int value)
   {
        return value % 2 == 0;
   }
}

Наконец-то мы сможем сделать это так ...

public extension IntExtension extends int
{
    public bool Even => this % 2 == 0;
}

Источник: https://blog.ndepend.com/c -8-0-функции-проблеск-будущее /

Как уже упоминалось @Psyonity, вы можете использовать conditionalWeakTable для добавления свойств к существующим объектам. В сочетании с динамическим ExpandoObject вы можете реализовать свойства динамического расширения в несколько строк:

using System.Dynamic;
using System.Runtime.CompilerServices;

namespace ExtensionProperties
{
    /// <summary>
    /// Dynamically associates properies to a random object instance
    /// </summary>
    /// <example>
    /// var jan = new Person("Jan");
    ///
    /// jan.Age = 24; // regular property of the person object;
    /// jan.DynamicProperties().NumberOfDrinkingBuddies = 27; // not originally scoped to the person object;
    ///
    /// if (jan.Age &lt; jan.DynamicProperties().NumberOfDrinkingBuddies)
    /// Console.WriteLine("Jan drinks too much");
    /// </example>
    /// <remarks>
    /// If you get 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create' you should reference Microsoft.CSharp
    /// </remarks>
    public static class ObjectExtensions
    {
        ///<summary>Stores extended data for objects</summary>
        private static ConditionalWeakTable<object, object> extendedData = new ConditionalWeakTable<object, object>();

        /// <summary>
        /// Gets a dynamic collection of properties associated with an object instance,
        /// with a lifetime scoped to the lifetime of the object
        /// </summary>
        /// <param name="obj">The object the properties are associated with</param>
        /// <returns>A dynamic collection of properties associated with an object instance.</returns>
        public static dynamic DynamicProperties(this object obj) => extendedData.GetValue(obj, _ => new ExpandoObject());
    }
}

Пример использования приведен в комментариях xml:

var jan = new Person("Jan");

jan.Age = 24; // regular property of the person object;
jan.DynamicProperties().NumberOfDrinkingBuddies = 27; // not originally scoped to the person object;

if (jan.Age < jan.DynamicProperties().NumberOfDrinkingBuddies)
{
    Console.WriteLine("Jan drinks too much");
}

jan = null; // NumberOfDrinkingBuddies will also be erased during garbage collection

Поскольку я недавно нуждался в этом, я посмотрел на источник ответа в:

c # расширяет класс, добавляя свойства

и создал более динамическую версию:

public static class ObjectExtenders
{
    static readonly ConditionalWeakTable<object, List<stringObject>> Flags = new ConditionalWeakTable<object, List<stringObject>>();

    public static string GetFlags(this object objectItem, string key)
    {
        return Flags.GetOrCreateValue(objectItem).Single(x => x.Key == key).Value;
    }

    public static void SetFlags(this object objectItem, string key, string value)
    {
        if (Flags.GetOrCreateValue(objectItem).Any(x => x.Key == key))
        {
            Flags.GetOrCreateValue(objectItem).Single(x => x.Key == key).Value = value;
        }
        else
        {
            Flags.GetOrCreateValue(objectItem).Add(new stringObject()
            {
                Key = key,
                Value = value
            });
        }
    }

    class stringObject
    {
        public string Key;
        public string Value;
    }
}

Вероятно, это может быть значительно улучшено (наименование, динамическое, а не строковое), в настоящее время я использую это в CF 3.5 вместе с хакерской ConditionalWeakTable ( https://gist.github.com/Jan-WillemdeBruyn/db79dd6fdef7b9845e217958db98c4d4 )

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top