С# Расширить класс, добавив свойства

Можно ли в С# расширить класс, не добавляя только функции, а свойства. Пример: у меня есть стандартная библиотека DLL, на которую я полагаюсь, и поставщик не хочет ее изменять.

Уже во всем кодексе я широко использовал класс DataCell и только теперь понял, что мне нужно добавить к нему дополнительное свойство, поскольку создание нового класса расширений, который наследуется от этого класса, просто не выглядит так, как если бы он работал + много переписывания.

DataCell [метаданные]

public class DataCell : Message
{
public int Field1;
public int Field2;
public DataCell()
{
 ..
} 
..
}

В принципе, я хочу добавить публичный int Flags; к этому классу. Поэтому я могу сделать это, не переписывая ничего (новый DataCell).Flags = 0x10;

Ответ 1

Прежде всего, вы, вероятно, должны пересмотреть свой подход. Но если все остальное не удается, вот как вы можете сортировать добавление свойства в закрытый класс:

using System;
using System.Runtime.CompilerServices;

namespace DataCellExtender
{

    #region sample 3rd party class
    public class DataCell
    {
        public int Field1;
        public int Field2;
    }
    #endregion

    public static class DataCellExtension
    {
        //ConditionalWeakTable is available in .NET 4.0+
        //if you use an older .NET, you have to create your own CWT implementation (good luck with that!)
        static readonly ConditionalWeakTable<DataCell, IntObject> Flags = new ConditionalWeakTable<DataCell, IntObject>();

        public static int GetFlags(this DataCell dataCell) { return Flags.GetOrCreateValue(dataCell).Value; }

        public static void SetFlags(this DataCell dataCell, int newFlags) { Flags.GetOrCreateValue(dataCell).Value = newFlags; }

        class IntObject
        {
            public int Value;
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            var dc = new DataCell();
            dc.SetFlags(42);
            var flags = dc.GetFlags();
            Console.WriteLine(flags);
        }
    }
}

Пожалуйста, не делайте этого, если не хотите. Будущие сторонники этого кода могут иметь для вас сильные слова, если есть более чистое решение, которое вы пропустили в пользу этого слегка взломанного подхода.

Ответ 2

Ну, вы можете, конечно, расширить класс и добавлять к нему только поля/свойства (хотя я бы отговорил использовать публичные поля в соответствии с вашим образцом). Однако, если другой код не использует ваш новый класс, поля не будут существовать в созданных объектах. Например, если в другом коде есть:

DataCell cell = new DataCell();

тогда у вас не будет полей Field1 и Field2.

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

Если вам интересно, можете ли вы добавить "поля расширения" так же, как добавлены методы расширения (например, public static void Foo(this DataCell cell)), то нет, это невозможно.

Ответ 3

Существует два способа добавления свойств к существующему классу

  • Добавить частичный класс, но это не сработает для вас, потому что частичные классы должны быть в одной сборке.

  • Наследовать этот класс в другом классе, который, насколько я знаю, будет лучшим решением для вас.

И нет, вы не можете использовать свойство расширения, например, метод расширения.