С# Расширить класс, добавив свойства
Можно ли в С# расширить класс, не добавляя только функции, а свойства. Пример: у меня есть стандартная библиотека 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
Существует два способа добавления свойств к существующему классу
-
Добавить частичный класс, но это не сработает для вас, потому что частичные классы должны быть в одной сборке.
-
Наследовать этот класс в другом классе, который, насколько я знаю, будет лучшим решением для вас.
И нет, вы не можете использовать свойство расширения, например, метод расширения.