I have an event broker that exposes an EventHandler<T> that allows observers to inspect the event argument and, if needed, modify it. While this works okay, I would ideally like to ensure that T only lives on the stack and, furthermore, that no component is able to take a reference to T, thereby extending its lifetime.
public class Game // mediator pattern
{
public event EventHandler<Query> Queries; // effectively a chain
public void PerformQuery(object sender, Query q)
{
Queries?.Invoke(sender, q);
}
}
Sadly, a ref struct cannot be used as a generic argument:
ref struct Query {} // EventHandler<Query> not allowed
And similarly I cannot imbue EventHandler's TEventArgs with any sort of 'use structs, pass by reference' mechanics.
Now, in C#, we can decide whether variables live on the stack on the heap, e.g. with stackalloc and such, so what I'm after, I guess, is just a way of getting something equivalent to a ref struct inside an event.
While stackalloc applied/wrapped in a very convoluted way may (probably) give you some semblance of variables live on the stack on the heap, it will not be what stackalloc is intended for.
So I'd rather propose to concentrate on the no component is able to take a reference to T, thereby extending its lifetime part.
To get it we need
Wrapper class (probably, but not necessary with corresponding interface)
Implementing IDisposable
And storing the actual T as WeakReference
It will be something like
public interface ITakeNoRefClass
{
void Change(string value);
}
public class TakeNoRefClass : ITakeNoRefClass
{
...
}
public class TakeNoRefClassWrapper : ITakeNoRefClass, IDisposable
{
private bool _isDisposed;
private readonly WeakReference<TakeNoRefClass> _takeNoRefWeakRef;
public TakeNoRefClassWrapper(WeakReference<TakeNoRefClass> takeNoRefWeakRef)
{
_takeNoRefWeakRef = takeNoRefWeakRef;
}
public void Change(string value)
{
Execute(o => o.Change(value));
}
private void Execute(Action<ITakeNoRefClass> action)
{
if (_disposed)
{
throw new ObjectDisposedException("You should not have taken this ref");
}
var target = _takeNoRefWeakRef.Target;
if (target == null)
{
throw new ObjectDisposedException("You should not have taken this ref");
}
action(target);
}
public void Dispose()
{
_isDisposed = true;
}
}
And it should be used like
public void CreateObjectAndRaiseEvents()
{
var target = new TakeNoRefClass();
// Passing it into a separate method to ensure that it won't be GC'ed before executing all event handlers.
RaiseEvents(target);
}
private void RaiseEvent(TakeNoRefClass target)
{
using (var wrapper = new TakeNoRefClassWrapper(new WeakReference<TakeNoRefClass>(target))
{
_event?.Invoke(wrapper);
}
}
Related
I'm trying to simplify a stack based interpreter with different stacks for each data type.
Essentially I have a bunch of instructions which look like this:
class Interpreter {
Stack<int> IntStack;
Stack<float> FloatStack;
Stack<char> CharStack;
// ... Continued for various other types.
}
class PushInt : Instruction {
Interpreter interpreter;
int value;
void Execute() {
interpreter.IntStack.Push(value);
}
}
class PopInt : Instruction {
Interpreter interpreter;
void Execute() {
interpreter.IntStack.Pop();
}
}
I have the same thing for PushFloat, PopFloat, PushChar, PopChar, etc
This screams "Generics" to me, what i'd love to do is define a Push<T> and Pop<T> instead. But I run into an issue here:
class Push<T> : Instruction {
Interpreter interpreter;
T value;
void Execute() {
interpreter.[What on earth goes here?].Push(value);
}
}
class Pop<T> : Instruction {
Interpreter interpreter;
void Execute() {
interpreter.[What on earth goes here?].Pop();
}
}
I thought, surely there must be a way to define Interpreter.Push<T>(value), but I end up with the same problem inside that method - i'm not sure how I can choose the correct stack based on the generic type parameter without some mess of casting.
Stuff I've tried Already:
One solution I've tried that sort of does work is to use static classes:
public static class ArgumentStack<T> {
public static Stack<T> Stack;
public static void Push(T value) {
Stack.Push(value);
}
public static T Pop() {
return Stack.Pop();
}
}
public class Push<T> : Instruction {
T value;
public override void Execute() {
ArgumentStack<T>.Push(Value);
}
}
public class Pop<T> : Instruction {
public override void Execute() {
ArgumentStack<T>.Pop();
}
}
But the problem with this is that if multiple interpreters are in use at once the whole thing starts to break down because only one instance of each stack type exists and they're shared across all interpreters.
It's frustrating because the static approach is pretty much exactly what I want in terms of usage, I just wish I could do this inside each Interpreter object rather than at the class level.
Any ideas?
You are right, generics are the key here. It seems like you simply want a class (Interpreter) to have a Stack property within it of an unknown type. From there you want to be able to add and remove items from that Stack using Push and Pop like this:
public class Interpreter<T>
{
public Stack<T> TypeStack { get; set; }
public Interpreter()
{
if (this.TypeStack == null)
{
this.TypeStack = new Stack<T>();
}
}
public void Push(T value)
{
this.TypeStack.Push(value);
}
public void Pop()
{
this.TypeStack.Pop();
}
}
You would use it like this:
var interpreter = new Interpreter<int>();
interpreter.Push(5);
interpreter.Pop();
I came up with a solution i'm reasonably happy with. But will leave the question open in case someone has something prettier.
I defined a static dictionary in the static generic class that maps interpreters to individual stacks, then defined an interpreter method which retrieve the correct generic stack. Code example below:
public static class ArgumentStack<T> {
public static Dictionary<Interpreter, Stack<T>> Stacks;
}
public class Interpreter {
public Stack<T> GetStack<T>() {
return ArgumentStack<T>.Stacks[this];
}
}
public class Push<T> : Instruction {
Interpreter interpreter;
T value;
public override void Execute() {
interpreter.GetStack<T>().Push(Value);
}
}
public class Pop<T> : Instruction {
Interpreter interpreter;
public override void Execute() {
interpreter.GetStack<T>().Pop();
}
}
Here's an approach you might be able to adapt. It appears that you want to be able to work with many different types while routing them each to their own stacks according to their type. (It's hard to understand quite where you're going with it, but I'll leave that to you.)
public class Interpreter
{
private readonly Dictionary<Type, Stack> _stacksByType = new Dictionary<Type, Stack>();
public void Push<T>(T item)
{
if (!_stacksByType.ContainsKey(typeof(T)))
{
_stacksByType.Add(typeof(T), new Stack());
}
_stacksByType[typeof(T)].Push(item);
}
public T Pop<T>()
{
// If we pop an empty stack it throws an InvalidOperationException
// so I'm throwing the same exception if there's no corresponding stack.
if (!_stacksByType.ContainsKey(typeof(T)))
throw new InvalidOperationException("There is nothing in the stack.");
return (T)_stacksByType[typeof(T)].Pop();
}
}
This allows Interpreter to encapsulate all of its various stacks. When you Push an item, it places it into a Stack according to its type. If the stack doesn't exist then it creates it.
When you Pop, it will pop from the stack according to type. If the stack for that type doesn't exist, it will throw the same exception as when the stack is empty.
Because we're managing type safety by controlling which Stack an item goes into we don't need the generic Stack<T>.
This encapsulation also allows us to avoid this:
interpreter.IntStack.Push(value);
It's better if classes outside of Interpreter don't know how it's managing all of this internally. Instead of telling the class which stack to put a value in, we can just give it the value and let it figure that out.
How,does one should call an event declared by interface so that all the classes that has implemented that interface get notified??
For example in structure like this,
public delegate void myDel(int value);
interface IEventCaller{
event myDel myDelEventCall;
}
public Class One : IEventCaller {
public event myDel myDelEventCall;
}
public Class Two : IEventCaller {
public event myDel myDelEventCall;
}
I want both class One and Two to get notify and act as event gets called, I am feeling somewhere I am going wrong direction , is it possible to do?
Actually what you want doesn't involve events. Events would be used by an object implementing IEventCaller to notify some object holding a reference to that object of some change. To invoke something on the object implementing IEventCaller would just require a method, for example Hello();
First, you need code that informs all the objects that implement this interface. To make that possible, you somewhere need to store a list of instances that want to get notified.
One solution would be to create a class that manages that list. Let's say like this
private static List<IEventCaller> eventCallers = new List<IEventCaller>();
public static void AddEventCaller(IEventCaller c)
{
eventCallers.Add(c);
}
public static void RemoveEventCaller(IEventCaller c)
{
eventCallers.Remove(c);
}
public static IEventCaller[] EventCallers
{
get { return eventCallers.ToArray() }
}
Of course this code needs to be thread safe, etc. I'd put all this into a singleton to be globally available.
Then, all objects that implement IEventCallers need to register/unregister accordingly. Thus, I'd also have them Implement IDisposable so that in the constructor you can do
public EventCallable()
{
Singleton.Instance.AddEventCaller(this);
}
and in the Dispose method you can do this:
public void Dispose(bool disposing)
{
Singleton.Instance.RemoveEventCaller(this);
}
Now the code that should notify every instance could just do this:
public void NotifyAll()
{
foreach (IEventCaller caller in Singleton.Instance.EventCallers)
caller.Hello();
}
I think you might be looking at this the other one around.
With events, you want to have an object which is the publisher, which is responsible for publishing the event and saying "hey guys, something just occurred and you should know about it", and you have your subscribers, which are the guys who say "Yo dawg, let me know when that thing occurs, so i can act on it".
What you can do is have the object which is responsible for the event occurring implement your interface:
public class Publisher : IEventCaller
{
public event MyDel MyDeleteEvent;
public void OnDeleteOccured()
{
var myDeleteEvent = MyDeleteEvent;
if (myDeleteEvent != null)
{
MyDeleteEvent(1);
}
}
}
And then have your One and Two objects register to that event occurring, where they pass a method which signature matches the delegate type of MyDel:
public class SubscriberOne
{
public void OnSomethingOccured(int value)
{
Console.WriteLine(value);
}
}
public class SubscriberTwo
{
public void OnSomethingOccured(int value)
{
Console.WriteLine(value);
}
}
And the registration goes:
void Main()
{
var publisher = new Publisher();
var subscriberOne = new SubscriberOne();
var subscriberTwo = new SubscriberTwo();
publisher.MyDeleteEvent += subscriberOne.OnSomethingOccured;
publisher.MyDeleteEvent += subscriberTwo.OnSomethingOccured;
}
We need to use an unmanaged library in our code that has static methods. I'd like to introduce the library operation as a dependency in my code. And apart from having static methods, the library has an initialization method and a settings method, both are global. So I can't just wrap this in an instance class, because if one instance changes a setting, all other instances will be affected, and if one instance gets initialized, all other instances will be reinitialized.
I thought about introducing it as a singleton class. This way it will be in an instance class, but there will only be one instance thus I won't have to worry about changing the settings or initialization. What do you think about this approach? I'm pretty new to the dependency injection pattern and I'm not sure if the singleton pattern is a good solution? What would your solution be to a similar case?
Edit: The initialization takes a parameter too, so I can't just lock the method calls and re-initialize and change settings every time it is called.
Edit 2: Here are the signatures of some methods:
public static void Initialize(int someParameter)
// Parameter can only be changed by re-initalization which
// will reset all the settings back to their default values.
public static float[] Method1(int someNumber, float[] someArray)
public static void ChangeSetting(string settingName, int settingValue)
If you only need to set the settings once at start up, then I would recommend making a non-static wrapper class which does all the initialization of the static class in its own static constructor. That way you can be assured that it will only happen once:
public class MyWrapper
{
public MyWrapper()
{
// Do any necessary instance initialization here
}
static MyWrapper()
{
UnManagedStaticClass.Initialize();
UnManagedStaticClass.Settings = ...;
}
public void Method1()
{
UnManagedStaticClass.Method1();
}
}
However, if you need to change the settings each time you call it, and you want to make your instances thread-safe, then I would recommend locking on a static object so that you don't accidentally overwrite the static settings while they're still in use by another thread:
public class MyWrapper
{
public MyWrapper()
{
// Do any necessary instance initialization here
}
static MyWrapper()
{
UnManagedStaticClass.Initialize();
}
static object lockRoot = new Object();
public void Method1()
{
lock (lockRoot)
{
UnManagedStaticClass.Settings = ...;
UnManagedStaticClass.Method1();
}
}
}
If you need to pass initialization parameters into your class's instance constructor, then you could do that too by having a static flag field:
public class MyWrapper
{
public MyWrapper(InitParameters p)
{
lock (lockRoot)
{
if (!initialized)
{
UnManagedStaticClass.Initialize(p);
initialized = true;
}
}
}
static bool initialized = false;
static object lockRoot = new Object();
public void Method1()
{
lock (lockRoot)
{
UnManagedStaticClass.Settings = ...;
UnManagedStaticClass.Method1();
}
}
}
If you also need to re-initialize each time, but you are concerned about performance because re-initializing is too slow, then the only other option (outside of the dreaded singleton) is to auto-detect if you need to re-initialize and only do it when necessary. At least then, the only time it will happen is when two threads are using two different instances at the same time. You could do it like this:
public class MyWrapper
{
public MyWrapper(InitParameters initParameters, Settings settings)
{
this.initParameters = initParameters;
this.settings = settings;
}
private InitParameters initParameters;
private Settings settings;
static MyWrapper currentOwnerInstance;
static object lockRoot = new Object();
private void InitializeIfNecessary()
{
if (currentOwnerInstance != this)
{
currentOwnerInstance = this;
UnManagedStaticClass.Initialize(initParameters);
UnManagedStaticClass.Settings = settings;
}
}
public void Method1()
{
lock (lockRoot)
{
InitializeIfNecessary();
UnManagedStaticClass.Method1();
}
}
}
I would use a stateless service class, and pass in state info for the static class with each method call. Without knowing any details of you class, I'll just show another example of this with a c# static class.
public static class LegacyCode
{
public static void Initialize(int p1, string p2)
{
//some static state
}
public static void ChangeSettings(bool p3, double p4)
{
//some static state
}
public static void DoSomething(string someOtherParam)
{
//execute based on some static state
}
}
public class LegacyCodeFacadeService
{
public void PerformLegacyCodeActivity(LegacyCodeState state, LegacyCodeParams legacyParams)
{
lock (_lockObject)
{
LegacyCode.Initialize(state.P1, state.P2);
LegacyCode.ChangeSettings(state.P3, state.P4);
LegacyCode.DoSomething(legacyParams.SomeOtherParam);
//do something to reset state, perhaps
}
}
}
You'll have to fill in the blanks a little bit, but hopefully you get the idea. The point is to set state on the static object for the minimum amount of time needed, and lock access to it that entire time, so no other callers can be affected by your global state change. You must create new instances of this class to use it, so it is fully injectable and testable (except the step of extracting an interface, which I skipped for brevity).
There are a lot of options in implementation here. For example, if you have to change LegacyCodeState a lot, but only to a small number of specific states, you could have overloads that do the work of managing those states.
EDIT
This is preferable to a singleton in a lot of ways, most importantly that you won't be able to accumulate and couple to global state: this turns global state in to non-global state if it is the only entry point to your static class. However, in case you do end up needing a singleton, you can make it easy to switch by encapsulating the constructor here.
public class LegacyCodeFacadeService
{
private LegacyCodeFacadeService() { }
public static LegacyCodeFacadeService GetInstance()
{
//now we can change lifestyle management strategies later, if needed
return new LegacyCodeFacadeService();
}
public void PerformLegacyCodeActivity(LegacyCodeState state, LegacyCodeParams legacyParams)
{
lock (_lockObject)
{
LegacyCode.Initialize(state.P1, state.P2);
LegacyCode.ChangeSettings(state.P3, state.P4);
LegacyCode.DoSomething(legacyParams.SomeOtherParam);
//do something to reset state, perhaps
}
}
}
I've got the following class:
public class Terminal : IDisposable
{
readonly List<IListener> _listeners;
public Terminal(IEnumerable<IListener> listeners)
{
_listeners = new List<IListener>(listeners);
}
public void Subscribe(ref Action<string> source)
{
source += Broadcast;
//Store the reference somehow?
}
void Broadcast(string message)
{
foreach (var listener in _listeners) listener.Listen(message);
}
public void Dispose()
{
//Unsubscribe from all the stored sources?
}
}
I've searched for a while and it appears that an argument passed with the ref keyword can't be stored. Trying to add the source argument to a list or to assign it to a field variable doesn't allow it to keep a reference to the actual delegate's original reference; so my questions are:
Is there a way to unsubscribe from all the sources without passing their references again?
If not, how can the class be changed in order to support it, but still maintain the subscription by passing a delegate through a method?
Is it possible to achieve it without using Reflection?
Is it possible to achieve it without wrapping the delegate/event in a class and then passing the class as a parameter for the subscription?
Thank you.
EDIT: It appears that without using a Wrapper or Reflection, there's no solution to the given problem. My intention was to make the class as much portable as possible, without having to wrap delegates in helper classes. Thanks everyone for the contributions.
Edit: Ok, that was a bad idea, so back to the basics:
I recommend creating a wrapper class over an Action:
class ActionWrapper
{
public Action<string> Action;
}
And restructuring your initial class to work with wrappers:
private ActionWrapper localSource;
public void Subscribe(ActionWrapper source)
{
source.Action += Broadcast;
localSource = source;
}
public void Dispose()
{
localSource.Action -= Broadcast;
}
Now you should get the desired results.
public class Terminal : IDisposable
{
List<IListener> _listeners;
List<Action<string>> _sources;
public Terminal(IEnumerable<IListener> listeners)
{
_listeners = new List<IListener>(listeners);
_sources = new List<Action<string>>();
}
public void Subscribe(ref Action<string> source)
{
_sources.Add( source );
source += Broadcast;
}
void Broadcast(string message)
{
foreach (var listener in _listeners) listener.Listen(message);
}
public void Dispose()
{
foreach ( var s in _sources ) s -= Broadcast;
}
}
I would suggest that the subscription method should return an implementation of a SubscriptionHelper class, which implements IDisposable. A simple implementation would be for SubscriptionHelper to hold a reference to the subscription list and a copy of the subscription delegate; the subscription list itself would be a List<SubscriptionHelper>, and the Dispose method for SubscriptionHelper would remove itself from the list. Note that if the same delegate gets subscribed multiple times, each subscription will return a different SubscriptionHelper; calling Dispose on a SubscriptionHelper will cancel the subscription for which it had been returned.
Such an approach would be much cleaner than the Delegate.Combine/Delegate.Remove method used by the normal .net pattern, whose semantics can get very strange if an attempt is made to subscribe and unsubscribe multi-target delegates.
EDIT:
Yep, my bad - delegates are immutable types, so adding a method to an invocation list will actually create a new delegate instance.
Which leads to an answer no to your question. To unsubscribe the delegate you need to remove your Broadcast method from the delegate's invocation list. This means creating a new delegate and assigning it to the original field or variable. But you cannot access the original once you're out of Subscribe method. Plus there can be other copies of that original field/variable that have your method on the invocation list. And there is no way for you to know about all of them and change there values.
I'd suggest to declare an interface with the event for your purpose. This will be quite flexible approach.
public interface IMessageSource
{
event Action<string> OnMessage;
}
public class MessageSource : IMessageSource
{
public event Action<string> OnMessage;
public void Send(string m)
{
if (OnMessage!= null) OnMessage(m);
}
}
public class Terminal : IDisposable
{
private IList<IMessageSource> sources = new List<IMessageSource>();
public void Subscribe(IMessageSource source)
{
source.OnMessage += Broadcast;
sources.Add(source);
}
void Broadcast(string message)
{
Console.WriteLine(message);
}
public void Dispose()
{
foreach (var s in sources) s.OnMessage -= Broadcast;
}
}
Original answer
Is there a particular reason why you pass source delegate as ref? You need this if you, for example, want to return a different delegate from the method.
Otherwise, the delegate is reference type, so you can subscribe to it without passing it as ref...
It's reasonably simple, but there are a few pitfalls. If you store a reference to the source objects, as most of the examples so far have proposed, the object won't be garbage collected. The best way to avoid this is to use an WeakReference, that will allow the GC to work properly.
So, all you have to do is this:
1) Add a list of sources to the class:
private readonly List<WeakReference> _sources = new List<WeakReference>();
2) Add the source to the list:
public void Subscribe(ref Action<string> source)
{
source += Broadcast;
//Store the reference
_sources.Add(new WeakReference(source));
}
3) And then just implement dispose:
public void Dispose()
{
foreach (var r in _sources)
{
var source = (Action<string>) r.Target;
if (source != null)
{
source -= Broadcast;
source = null;
}
}
_sources.Clear();
}
That said, there's also the question of why the Action must be passed as a ref. In the current code, there's no reason for that. Anyway, it doesn't affect the problem or the solution.
Perhaps, instead of trying to store a reference to the delegate, have what calls Subscribe use its reference to the object with the delegate to create actions for the subscription and unsubscription . Its an additional parameter, but its still straightforward.
public void Subscribe(Action<Action<string>> addHandler,Action<Action<string>> removeHandler)
{
//Prevent error for possibly being null in closure
Action<string> onEvent = delegate { };
//Broadcast when the event occurs, unlisten after (you could store onEvent and remove handler yourself)
onEvent = (s) => { Broadcast(s); removeHandler(onEvent); };
addHandler(onEvent);
}
And an example subscribing.
public event Action<string> CallOccured;
public void Program()
{
Subscribe(a => CallOccured += a, a => CallOccured -= a);
CallOccured("Hello");
}
I have a method which should return a snapshot of the current state, and another method which restores that state.
public class MachineModel
{
public Snapshot CurrentSnapshot { get; }
public void RestoreSnapshot (Snapshot saved) { /* etc */ };
}
The state Snapshot class should be completely opaque to the caller--no visible methods or properties--but its properties have to be visible within the MachineModel class. I could obviously do this by downcasting, i.e. have CurrentSnapshot return an object, and have RestoreSnapshot accept an object argument which it casts back to a Snapshot.
But forced casting like that makes me feel dirty. What's the best alternate design that allows me to be both type-safe and opaque?
Update with solution:
I wound up doing a combination of the accepted answer and the suggestion about interfaces. The Snapshot class was made a public abstract class, with a private implementation inside MachineModel:
public class MachineModel
{
public abstract class Snapshot
{
protected internal Snapshot() {}
abstract internal void Restore(MachineModel model);
}
private class SnapshotImpl : Snapshot
{
/* etc */
}
public void Restore(Snapshot state)
{
state.Restore(this);
}
}
Because the constructor and methods of Snapshot are internal, callers from outside the assembly see it as a completely opaque and cannot inherit from it. Callers within the assembly could call Snapshot.Restore rather than MachineModel.Restore, but that's not a big problem. Furthermore, in practice you could never implement Snapshot.Restore without access to MachineModel's private members, which should dissuade people from trying to do so.
Can MachineModel and Snapshot be in the same assembly, and callers in a different assembly? If so, Snapshot could be a public class but with entirely internal members.
I could obviously do this by
downcasting, i.e. have CurrentSnapshot
return an object, and have
RestoreSnapshot accept an object
argument which it casts back to a
Snapshot.
The problem is that somebody could then pass an instance of an object which is not Snapshot.
If you introduce an interface ISnapshot which exposes no methods, and only one implementation exists, you can almost ensure type-safety at the price of a downcast.
I say almost, because you can not completely prevent somebody from creating another implementation of ISnapshot and pass it, which would break. But I feel like that should provide the desired level of information hiding.
You could reverse the dependency and make Snapshot a child (nested class) of MachineModel. Then Snapshot only has a public (or internal) Restore() method which takes as a parameter an instance of MachineModel. Because Snapshot is defined as a child of MachineModel, it can see MachineModel's private fields.
To restore the state, you have two options in the example below. You can call Snapshot.RestoreState(MachineModel) or MachineModel.Restore(Snapshot)*.
public class MachineModel
{
public class Snapshot
{
int _mmPrivateField;
public Snapshot(MachineModel mm)
{
// get mm's state
_mmPrivateField = mm._privateField;
}
public void RestoreState(MachineModel mm)
{
// restore mm's state
mm._privateField = _mmPrivateField;
}
}
int _privateField;
public Snapshot CurrentSnapshot
{
get { return new Snapshot(this); }
}
public void RestoreState(Snapshot ss)
{
ss.Restore(this);
}
}
Example:
MachineModel mm1 = new MachineModel();
MachineModel.Snapshot ss = mm1.CurrentSnapshot;
MachineModel mm2 = new MachineModel();
mm2.RestoreState(ss);
* It would be neater to have Snapshot.RestoreState() as internal and put all callers outside the assembly, so the only way to do a restore is via MachineModel.RestoreState(). But you mentioned on Jon's answer that there will be callers inside the same assembly, so there isn't much point.
This is an old question, but i was looking for something very similar and I ended up here and between the information reported here and some other I came up with this solution, maybe is a little overkill, but this way the state object is fully opaque, even at the assembly level
class Program
{
static void Main(string[] args)
{
DoSomething l_Class = new DoSomething();
Console.WriteLine("Seed: {0}", l_Class.Seed);
Console.WriteLine("Saving State");
DoSomething.SomeState l_State = l_Class.Save_State();
l_Class.Regen_Seed();
Console.WriteLine("Regenerated Seed: {0}", l_Class.Seed);
Console.WriteLine("Restoring State");
l_Class.Restore_State(l_State);
Console.WriteLine("Restored Seed: {0}", l_Class.Seed);
Console.ReadKey();
}
}
class DoSomething
{
static Func<DoSomething, SomeState> g_SomeState_Ctor;
static DoSomething()
{
Type type = typeof(SomeState);
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle);
}
Random c_Rand = new Random();
public DoSomething()
{
Seed = c_Rand.Next();
}
public SomeState Save_State()
{
return g_SomeState_Ctor(this);
}
public void Restore_State(SomeState f_State)
{
((ISomeState)f_State).Restore_State(this);
}
public void Regen_Seed()
{
Seed = c_Rand.Next();
}
public int Seed { get; private set; }
public class SomeState : ISomeState
{
static SomeState()
{
g_SomeState_Ctor = (DoSomething f_Source) => { return new SomeState(f_Source); };
}
private SomeState(DoSomething f_Source) { Seed = f_Source.Seed; }
void ISomeState.Restore_State(DoSomething f_Source)
{
f_Source.Seed = Seed;
}
int Seed { get; set; }
}
private interface ISomeState
{
void Restore_State(DoSomething f_Source);
}
}