Какие инструменты/библиотеки существуют, который возьмет структуру и автоматически генерирует неизменную обертку и также класс "разработчика" для того, чтобы инкрементно создать новые экземпляры?
Пример ввел:
struct Foo
{
public int apples;
public int oranges;
public Foo Clone() {return (Foo) base.MemberwiseClone();}
}
Пример произвел:
public class ImmutableFoo // could probably be a struct
{
private Foo snapshot;
internal ImmutableFoo(Foo value) { this.snapshot = value; }
public FooBuilder Builder() { return new FooBuilder(snapshot); }
public int Apples { get { return snapshot.apples; } }
public int Oranges { get { return snapshot.oranges; } }
}
public class FooBuilder
{
private Foo state;
public int Apples { get { return state.apples; } set { state.apples = value; } }
public int Oranges { get { return state.oranges; } set { state.oranges = value; } }
public FooBuilder() { }
internal FooBuilder(Foo toCopy) { state = toCopy.Clone(); }
public ImmutableFoo Build()
{
ImmutableFoo result = new ImmutableFoo(state);
state = state.Clone();
return result;
}
}
Такой "инструмент" мог быть плагином IDE или мог генерировать новый класс во времени выполнения с помощью отражения.
Пример находится в C#, но я интересовался бы решением для любого языка OO со статическим контролем типов (Java, Scala, C++ и т.д.)
Желательные функции:
Equals()
и GetHashCode()
и любые методы интерфейса)IFooReader
интерфейс, содержащий свойства только для чтения для каждого участника структуры, реализованного и неизменным и разработчиком.List
-> ReadOnlyCollection
или подобный.Clone
метод, который будет предопределен"Вы не должны использовать инструмент как это, потому что..." ответы также приветствуются.
Вот четыре возможных решения.
1) Используйте CodeDOM для генерации кода на C# или VB. Это также позволит вам использовать расширения visual studio для генерации кода в файлах дизайнера. Аналогично некоторым встроенным инструментам, которые уже предлагает visual studio - например, тем, которые генерируют обертки для вызовов веб-сервисов и т.д. К сожалению, я не очень много знаю о расширении Visual Studio.
2) Используйте библиотеку Mono.Cecil для анализа вашей сборки после сборки. Затем вы можете переписать сборку с включением новых типов.
3) Использовать PostSharp. Я не так много знаю об этой библиотеке, поэтому, возможно, вы не сможете добавить новые типы в вашу сборку, но я знаю, что вы можете внедрять IL в методы. В ней также есть много хороших вещей, которые позволяют легко делать это с помощью атрибутов. Таким образом, вы можете сделать следующее -
[GenerateImmutable]
struct Foo
{
public int apples;
public int oranges;
public Foo Clone() {return (Foo) base.MemberwiseClone();}
}
4) Используйте встроенные библиотеки Reflection.Emit для генерации новой сборки с неизменяемыми типами.
Предполагая, что вы говорите о контейнере сервлета, обработка сеанса возвращается. См. в соответствующей части руководства по JavaEE . Он охватывает API сеанса, а также то, как отслеживаются сеансы (перезапись файлов cookie или URL).
-121--4817553- Использование и
подходит для коротких команд, но эта одиночная линия может быть очень длинной и очень быстрой. Когда это произойдет, переключитесь на многострочный синтаксис.
FOR /r %%X IN (*.txt) DO (
ECHO %%X
DEL %%X
)
Размещение (
и )
имеет значение. Круглые скобки после DO
должны быть помещены в ту же строку, в противном случае пакетный файл будет неправильным.
Подробнее см. , если/? | найти/V «»
.
Зачем беспокоиться о построителе?
У вас есть (противная) изменяемая структура, но если вы должны использовать ее напрямую, а не создавать громоздкий и ненужный Builder.
Меня несколько беспокоит, что у вас есть достаточное количество этих структур, чтобы вы почувствовали, что вам нужно автоматически генерировать обертки такого рода. Моя кишечная реакция в том, что ты делаешь это неправильно...
Если целью неизменяемой оболочки является просто хранение снимка, то просто используйте что-то подобное:
public struct Snapshot<T> where t : struct
{
private readonly T data;
public Snapshot(T value) { this.data = value; }
public T Data { get { return data; } }
}
Переданная структура гарантированно больше никогда не изменится, но вы можете получить доступ ко всем значениям на ней напрямую (и изменения этих результатов происходят на копии, созданной при вызове базовой функции get_Data)