c# call a method whenever another method ends? - c#

Although this question might sound stupid at first glance, please hear me out.
c#'s get{} and set{} methods are increadibly usefull in situations when you do not know how you porgramming goals will evolve while you build your code. I enjoyed their freedom many a time and now I wonder if there is something similar for methods but in a bit different light.
As I am working in gamedev, it is a very common practice to extend/update/improve existing code day-in day-out. Therefore, one of the patterns I taught myself to follow is to never use "return" statement more than once in the most of my methods.
The reason why I do this is to always be able to write something at the bottom of the method and be sure that the line I have written is always called 100% of the time once my method ENDS.
Here is an example:
public void Update()
{
UpdateMovement();
if (IsIncapacitated)
return;
if (IsInventoryOpened)
{
UpdateInventory();
return;
}
if (Input.HasAction(Actions.Fire))
{
Fire();
return;
}
else if (Input.HasAction(Actions.Move))
{
Move(Input.Axis);
return;
}
}
Now imagine that this method is called dozens of times in many places across the entirety of your project. And then the next day you decide that you need to call UpdatePhysics() method at the very end of your Update() method. In this case there are only 4 returns, it could be much worse in reality.
Then imagine that such decesions happen several times a day every day. Bad planning you may say? I might agree with you, but I do think that freedom of development is essential in modern coding. I don't think you should kill yourself trying to anticipate every turn your project might take before you start writing code.
One way to insure that problems like the one I described above never happen is to rewrite the method as follows:
public void Update()
{
UpdateMovement();
if (!IsIncapacitated)
{
if (IsInventoryOpened)
{
UpdateInventory();
}
else
{
if (Input.HasAction(Actions.Fire))
{
Fire();
}
else if (Input.HasAction(Actions.Move))
{
Move(Input.Axis);
}
}
}
}
In this case you can always add a line at the bottom and be sure it will always get called nomatter what.
So I wanted to ask if there is another approach that could allow for placing "return"-s wherever you wish while still being able to add extra code easily at the bottom of the method any time. Maybe there is any form of syntax in c# that does it for you? Or maybe there is a better coding practice that eliminates such problem?
UPDATE: As I started receiving answers, I realized that I need to clarify things a bit.
'try/catch/finally' is an overkill - I will never use them. They have severe performance penalty on catch(), they screw up 'Edit and continue' feature in Visual Studio and they just look ugly.
Idealy I need to be able to access local variables in the Update() method from any code I decide to add at the end of the method,
When I wrote the question, I already had an answer - nesting. My second code sample has no returns and, therefore I can add code to the very bottom of the method and it will work 100% of the time, while I will be able to use local variables. Nesting is bad though, and that is why I am here searching for a BETTER solution.
UPDATE 2: I was actually mistaken about try/catch because I did not know that you can skip catch alongside it's performance penalties and only have finally. However, this solution is still worse than the nesting solution provided in the question, because in your newly added finally block you no longer can use return statements. So basically you can do whatever you want when you write the method the first time, but once you extend it - you are back to nesting.

One simple suggestion is to wrap your function. For example:
public void UpdateCall()
{
Update();
AfterUpdate code goes here.
}

Using a try/finally block should work;
public void Update()
{
try
{
UpdateMovement();
if (IsIncapacitated)
return;
if (IsInventoryOpened)
{
UpdateInventory();
return;
}
if (Input.HasAction(Actions.Fire))
{
Fire();
return;
}
else if (Input.HasAction(Actions.Move))
{
Move(Input.Axis);
return;
}
}
finally
{
//this will run, no matter what the return value
}
}
The performance costs of using try/finally (not try/catch!) are minimal
You cannot use return in the finally block;
If you were able to return a different value from the Finally block,
this value would always be returned, whatever the outcome of the
instructions above. It just wouldn't make sense..

I suggest wrapping the code into try..finally block:
public void Update() {
try {
...
// you can return
if (someCondition)
return;
...
// throw exceptions
if (someOtherCondition)
throw...
...
}
finally {
// However, finally will be called rain or shine
}
}

You can use try-catch-finally (C#-Reference) without a catch block.
try
{
//your business logic here
}
finally
{
//will be called anytime if you leave the try block
// i.e. if you use a return or a throw statement in the try block
}

With the modern c# 8 syntax you may introduce some disposable 'ScopeFinalizer' object or name whatever you want:
public class ScopeFinalizer : IDisposable
{
private Action delayedFinalization;
public ScopeFinalizer(Action delayedFinalization)
{
this.delayedFinalization = delayedFinalization ?? throw new ArgumentNullException(nameof(delayedFinalization));
}
public void Dispose()
{
delayedFinalization();
}
}
//usage example
public async Task<bool> DoWorkAsyncShowingProgress()
{
ShowActivityIndicator();
using var _ = new ScopeFinalizer(() =>
{
// --> Do work you need at enclosure scope leaving <--
HideActivityIndicator();
});
var result = await DoWorkAsync();
HandleResult(result);
//etc ...
return true;
}
Useful link:
https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#using-declarations

Don't use the returns as it makes your code smelly.
public void Update()
{
UpdateMovement();
if (IsIncapacitated){
return;
}
if (IsInventoryOpened)
{
UpdateInventory();
}
else if (Input.HasAction(Actions.Fire))
{
Fire();
}
else if (Input.HasAction(Actions.Move))
{
Move(Input.Axis);
}
}
Also, your second solution has too much nesting, also confusing and smelly.

A problem with the current approach is that it requires changes to the Update() method whenever we want to add a new action.
Another approach is to remove the hard-coding of the update actions and configure the class with a set of update actions.
From the code given here we have
Actions that always happen (e.g. UpdateMovement)
Actions that happen if a test is passed (e.g. UpdateInventory)
Actions that cause a return if they are executed (e.g. Fire())
We can encapsulate these in an interface
public interface IUpdateAction
{
bool ShouldUpdate();
// return true if we want this to be the last action to be executed
bool Update();
}
and wrap various actions and decisions in the class using
public class DelegateUpdateAction : IUpdateAction
{
private Func<bool> _updateAction;
private Func<bool> _shouldUpdateCheck;
public DelegateUpdateAction(Action action, bool isLastAction = false, Func<bool> shouldUpdateCheck = null)
: this(() =>
{
action();
return isLastAction;
},
shouldUpdateCheck)
{ }
public DelegateUpdateAction(Func<bool> updateAction, Func<bool> shouldUpdateCheck = null)
{
if(updateAction == null)
{
throw new ArgumentNullException("updateAction");
}
_updateAction = updateAction;
_shouldUpdateCheck = shouldUpdateCheck ?? (() => true);
}
public bool ShouldUpdate()
{
return _shouldUpdateCheck();
}
public bool Update()
{
return _updateAction();
}
}
To replicate the example we could use
public class Actor
{
private IEnumerable<IUpdateAction> _updateActions;
public Actor(){
_updateActions = new List<IUpdateAction>{
new DelegateUpdateAction((Action)UpdateMovement),
new DelegateUpdateAction((()=>{ }), true, () => IsIncapacitated),
new DelegateUpdateAction((Action)UpdateInventory, true, () => IsInventoryOpened),
new DelegateUpdateAction((Action)Fire, true, () => Input.HasAction(Actions.Fire)),
new DelegateUpdateAction(() => Move(Input.Axis), true, () => Input.HasAction(Actions.Move))
};
}
private Input Input { get; set; }
public void Update()
{
foreach(var action in _updateActions)
{
if (action.ShouldUpdate())
{
if (action.Update())
break;
}
}
}
#region Actions
private bool IsIncapacitated { get; set; }
private bool IsInventoryOpened { get; set; }
private void UpdateMovement()
{
}
private void UpdateInventory()
{
}
private void Fire()
{
}
private void Move(string axis)
{
}
#endregion
}
The actions are executed in the order in which they are registered, so this gives us the ability to inject a new action into the execution sequence at any point.
UpdateMovement() always happens and doesn't return
IsIncapacitated() is a test with a null action. It returns if executed so we get our 'do-nothing-else-if-incapacitated' behaviour
UpdatedInventory() occurs if the inventory is open and then returns
Each of the HasAction checks return if executed.
Note If I have read the question better before writing the code I would have reversed the defaults as most actions seem to be 'return if executed'.
If we need to add 'UpdatePhysics()', we add a method to the class and add an entry in the appropriate place in the list of update actions. No changes to the Update method.
If we have derived classes with different actions we can add the facility to add (or remove) actions in the derived classes and either inherit and modify the default actions or replace them with a different set.

After seeing the other solutions I can't think of a truly dynamic solution that has only the functions you want to call in the update loop.
Here are some ideas though I doubt any of them are better than making a good design. Joe C has the correct idea of how you should structure this kind of thing.
You could make a container of actions that need to be performed each update loop. Remove and add specific actions depending on the changes to circumstances. Such as a IsNowIncapacitated event that remove the Handling action from the list. Though I have little experience with actions, I believe you can set up delegates that the actions point to. Not sure what the cost to performance is.
A temporary thing you could do so you can keep adding logic is have your return statements return a void function with some constant logic you want performed, though all it really will do is separate your update code between two methods. It is not very neat or as efficient as structuring your code appropriately like in Joe C's example.
public void PostUpdate()
{
//stuff that always happens
PhysicsUpdate();
}
public void Update()
{
UpdateMovement();
if (IsIncapacitated)
return PostUpdate();
if (IsInventoryOpened)
{
UpdateInventory();
return PostUpdate();
}
}

Related

Getting all results from Func call

The concept of delegates aren't too new to me but I cannot seem to find out how to get all results from a Func delegates. More specifically, I have a class that has a Func delegate that returns a type bool. Something like this...
private Func<Employee, Shift, bool> qualificationCheckCallback;
There are both 'register' and 'unregister' methods for the callback as well. My goal is to see if any of the methods stored in the delegate return false when invoked later in code. Any insight you may have on this issue is much appreciated! Thanks.
You are using the wrong pattern. I'd recommend storing a list of these delegates and iterating over the list, rather than using multidelegates to call multiple targets.
You can make this work (if you need to) by changing the signature to include a "state" variable that is passed by reference to each caller:
private Action<Employee, Shift, QualCheckState> qualificationCheckCallback;
public class QualCheckState { public bool Passed { get; set; } }
// Call it thus:
var state = new QualCheckState { Passed = true }; // Hope for the best
qualificationCheckCallback(someEmployee, someShift, state);
if (state.Passed) {
// Assume everyone passed
}
Keep in mind, this requires the callees to honor the signature, and not overwrite anyone else's failed state:
public void SomeCallee(Employee e, Shift s, State state) {
// If some other check failed, don't bother doing our check.
if (!state.Passed) return;
// Do some check here
if (checkFailed) state.Passed = false;
}
Of course, you can also extend this pattern to make it safer:
public class QualCheckState {
private List<bool> _results = new List<bool>();
public bool Passed { get { return _results.All(s => s); }
public void RecordResult(bool result) {
_results.Add(result);
}
}
As mentioned in Andrew's answer, if you simply invoke qualificationCheckCallback like a normal method, you'll only get back the return value from one of the methods. For this reason, it's pretty unusual to have multicast delegates that have a return value.
If your goal is to see if at least one of the methods stored in your delegate returns false, you'll need to invoke the methods individually. Here is one way to do that using the Delegate.GetInvocationList() method:
bool hasAtLeastOneFalse = false;
if (qualificationCheckCallback != null)
{
foreach(var f in qualificationCheckCallback.GetInvocationList()
.Cast<Func<Employee, Shift, bool>>())
{
if (!f(employee, shift))
{
hasAtLeastOneFalse = true;
// break; // If you don't care about invoking all delegates, you can choose to break here.
}
}
}
Console.WriteLine(hasAtLeastOneFalse);
I'm not suggesting this is a good practice, but it can be done.
A quick search on MSDN found this thread:
https://social.msdn.microsoft.com/Forums/en-US/38a638fe-4a7d-44d6-876c-729d90c20737/how-to-get-return-value-from-delegate?forum=csharplanguage
The problem with events is that the return values cannot be fully
trusted. You will get only one return value no matter how many
subscribers that you have for the event. The central issue is that
you cannot reliably determine which subscriber produced the return
value. The beauty of the .NET Event Model is the anonymity that it
uses. That means event subscribers are completely abstracted from the
event publishers.

Checking a private field vs catching an exception

I have a class from a third-party assembly (so I can't edit it):
public class MyClass
{
private bool _loggedIn;
public void Login() {_loggedIn = true;}
public void Logout() {
if (!_loggedIn) throw new InvalidOperationException();
_loggedIn = false;
}
}
Now, suppose I have an instance of MyClass (for which I don't know _loggedIn), and I need call LogOut. Which of the following methods of avoiding a fatal exception will generally be faster? (any other method would be fine too):
To call LogOut, and if _loggedIn == false, just catch the exception
To use reflection to check that _loggedIn == true, and only call LogOut if so
It depends on the invariants you expect to see in your application.
1. If you expect to have a lot of MyClass having different state(logged in, logged off), then it is better to avoid overhead of exception (because exception is Exceptional situation) and use some specific public IsLoggedIn property (obviously to avoid Reflection) or some TryXxxxx-like methods.
And even if you can't modify the original code no one stops you from wrapping it:
public class MyWrappedClass
{
public Boolean IsLoggedIn {get; private set;}
private MyClass m_Log;
public MyWrappedClass ()
{
this.m_Log = new MyClass();
this.IsLoggedIn = false;
}
public void Log()
{
try
{
this.m_Log.LogIn();
this.IsLoggedIn = true;
}
catch
{
this.IsLoggedIn = false;
}
}
public void LogOut()
{
try
{
this.m_Log.LogOut();
this.IsLoggedIn = false;
}
catch
{
this.IsLoggedIn = true;
}
}
}
You could even go further and implement IDisposable interface with it to avoid manual LogIn-LogOut management:
public class MyWrappedClass
{
private class LogSessionToken : IDisposable
{
private MyWrappedClass parent;
public LogSessionToken (MyWrappedClass parent)
{
parent.LogIn();
}
public void Dispose()
{
parent.LogOut();
}
}
public IDisposable LogSession()
{
return new LogSessionToken (this);
}
// ...
}
And use it like
using (var logToken = wrappedInstance.LogSession)
{
// do the work.
} // No need to worry about manual LogOut
2. If you expect to use only few of MyClass in a proper fashion, then it would be a better idea to not handle exception at all - if something wrong happened then it is some programming error thus the program shall be terminated.
First, if your class doesn't expose at least a read-only property for LoggedIn, there sounds like a fairly large design flaw.
For speed, using reflection will generally be faster, particularly if you cache the FieldInfo or build a Func<bool> using System.Linq.Expressions. This is because Exceptions collect lots of debug information when thrown, including a StackTrace, which can be expensive.
As with anything, though, it is often best to test such operations, as there are sometime optimizations or other factors that may surprise you.
If the pattern if (CanFoo) Foo(); appears very much, that tends to imply very strongly that either:
A properly-written client would know when it can or cannot call Foo. The fact that a client doesn't know suggest that it's probably deficient in other ways.
The class exposing CanFoo and Foo should also expose a method which will Foo if possible and appropriate (the method should throw if unable to establish expected post-conditions, but should return silently if the post-conditions were established before the call)
In cases where a class one does not control should provide such a method but doesn't, the cleanest approach may be to write one's own wrapper method whose semantics mirror those the missing method should have had. If a later version of the class implements the missing method, changing one's code to use that implementation may be easier than refactoring lots of if (CanFoo) constructs.
BTW, I would suggest that a properly-designed class should allow calling code to indicate whether it is expecting a transition from logged-in state to logged-out state, or whether it wants to end up in logged-out state but it doesn't care how it gets there. Both kinds of semantics have perfectly legitimate uses; in cases where the first kind would be appropriate, having a LogOut method throw an exception if called on a closed session would be a good thing, but in cases where client code merely wants to ensure that it is logged out, having an EnsureLoggedOut method that could be invoked unconditionally would be cleaner than having to add extra client-side code for that purpose.

Which design pattern should I use?

I have the following code which executes in sequence, method after another.
I load the request, perform a couple of checks like checking if a response already exists for this request, if not, I call the service and receive the response which I save to the DB.
I was looking for a design pattern I can use in such a case, I thought of posting this here and get some ideas.
public class Manager
{
public void PutRequest()
{
//Do Something
if (loadRequest())
{
callService();
//Do Something
saveResponse();
}
}
private bool loadRequest()
{
bool isExist = checkIfResponseExists();
if (!isExist)
{
// If false, load request from DB
}
return !isExist;
}
private bool checkIfDataExists()
{
//Check if a response already exists in the DB for this request
}
private void callService()
{
//Call the service and receive the response
}
private void saveResponse()
{
//Store the response in the DB
}
}
Patterns are used for solving some problems. What problem your current code have? I don't see any duplicated code, beside names of methods. There is no pattern, which fixes method naming problem.
Yes, your code need some refactoring, but not to patterns. Better class and method naming is a first step. Also, I'd removed field isExist.
public class Manager
{
public void PutRequest()
{
//Do Something
if (!CheckIfResponseExists()) // returns boolean value
LoadRequestFromDB()
CallService();
//Do Something
SaveResponse();
}
}
Check the design pattern called Strategy, it defines an interface common to all supported algorithms and each concrete strategy implements an algorithm
http://www.oodesign.com/strategy-pattern.html
It seems like it'd be more useful for several of these methods to be functions. So instead of having a method who's responsibility is to both check for a condition and do some other actions, you have a function that checks for a condition then the method that called it does some action depending on the result. (Kind of the SRP applied to methods...)
public void DoAllTheThings!() // Oops, Ruby syntax creeping in :P
{
if(!WeCanDoIt())
{
MakeItSo(); // So that we can do it...
}
NowWeCanDoAllTheThings();
}
private bool WeCanDoIt() {}
private void MakeItSo() {}
private void NowWeCanDoAllTheThings() {}
Command + Composite.
Some people consider the use of an if/then Command - in your case that would be in putRequest - in a Composite a kind of Chain Of Responsibility.
While selecting a pattern you should consider scalability of the application
One of the pattern you can apply is state pattern
There will be two states.
Response is already there
Need to process the new response

Checking constraints using IDisposable -- madness or genius?

I ran across a pattern in a codebase I'm working on today that initially seemed extremely clever, then later drove me insane, and now I'm wondering if there's a way to rescue the clever part while minimizing the insanity.
We have a bunch of objects that implement IContractObject, and a class InvariantChecker that looks like this:
internal class InvariantChecker : IDisposable
{
private IContractObject obj;
public InvariantChecker(IContractObject obj)
{
this.obj = obj;
}
public void Dispose()
{
if (!obj.CheckInvariants())
{
throw new ContractViolatedException();
}
}
}
internal class Foo : IContractObject
{
private int DoWork()
{
using (new InvariantChecker(this))
{
// do some stuff
}
// when the Dispose() method is called here, we'll throw if the work we
// did invalidated our state somehow
}
}
This is used to provide a relatively painless runtime validation of state consistency. I didn't write this, but it initially seemed like a pretty cool idea.
However, the problem arises if Foo.DoWork throws an exception. When the exception is thrown, it's likely that we're in an inconsistent state, which means that the InvariantChecker also throws, hiding the original exception. This may happen several times as the exception propagates up the call stack, with an InvariantChecker at each frame hiding the exception from the frame below. In order to diagnose the problem, I had to disable the throw in the InvariantChecker, and only then could I see the original exception.
This is obviously terrible. However, is there any way to rescue the cleverness of the original idea without getting the awful exception-hiding behavior?
I don't like the idea of overloading the meaning of using in this way. Why not have a static method which takes a delegate type instead? So you'd write:
InvariantChecker.Check(this, () =>
{
// do some stuff
});
Or even better, just make it an extension method:
this.CheckInvariantActions(() =>
{
// do some stuff
});
(Note that the "this" part is needed in order to get the C# compiler to look for extension methods that are applicable to this.) This also allows you to use a "normal" method to implement the action, if you want, and use a method group conversion to create a delegate for it. You might also want to allow it to return a value if you would sometimes want to return from the body.
Now CheckInvariantActions can use something like:
action();
if (!target.CheckInvariants())
{
throw new ContractViolatedException();
}
I would also suggest that CheckInvariants should probably throw the exception directly, rather than just returning bool - that way the exception can give information about which invariant was violated.
This is a horrid abuse of the using pattern. The using pattern is for disposing of unmanaged resources, not for "clever" tricks like this. I suggest just writing straight forward code.
If you really want to do this:
internal class InvariantChecker : IDisposable
{
private IContractObject obj;
public InvariantChecker(IContractObject obj)
{
this.obj = obj;
}
public void Dispose()
{
if (Marshal.GetExceptionCode() != 0xCCCCCCCC && obj.CheckInvariants())
{
throw new ContractViolatedException();
}
}
}
Instead of this:
using (new InvariantChecker(this)) {
// do some stuff
}
Just do this (assuming you don't return from do some stuff):
// do some stuff
this.EnforceInvariants();
If you need to return from do some stuff, I believe some refactoring is in order:
DoSomeStuff(); // returns void
this.EnforceInvariants();
...
var result = DoSomeStuff(); // returns non-void
this.EnforceInvariants();
return result;
It's simpler and you won't have the problems you were having before.
You just need a simple extension method:
public static class InvariantEnforcer {
public static void EnforceInvariants(this IContractObject obj) {
if (!obj.CheckInvariants()) {
throw new ContractViolatedException();
}
}
}
Add a property to the InvariantChecker class that allows you to suppress the check/throw.
internal class InvariantChecker : IDisposable
{
private IContractObject obj;
public InvariantChecker(IContractObject obj)
{
this.obj = obj;
}
public bool Suppress { get; set; }
public void Dispose()
{
if (!this.Suppress)
{
if (!obj.CheckInvariants())
{
throw new ContractViolatedException();
}
}
}
}
internal class Foo : IContractObject
{
private int DoWork()
{
using (var checker = new InvariantChecker(this))
{
try
{
// do some stuff
}
catch
{
checker.Suppress = true;
throw;
}
}
}
}
If you current problem is to get original exception - go to Debug -> Exceptions and check "thrown" for all CLR exceptions. It will break when exception is thrown and as result you'll see it first. You may need to also turn off tools->options->debug->"my code only" option if exceptions are throw from "not your code" from VS point of view.
What is needed to make this nice is a clean means of finding out whether an exception is pending when Dispose is called. Either Microsoft should provide a standardized means of finding out at any time what exception (if any) will be pending when the current try-finally block exits, or Microsoft should support an extended Dispose interface (perhaps DisposeEx, which would inherit Dispose) which would accept a pending-exception parameter.

How to identify an anonymous function

I have a class that creates a List<Action<int>> and holds on to them until a later time. This class can add and remove delegates from this list. This works well as long as people don't get too fancy. To combat anonymous function (which can't be removed) I check against the target of the delegate being null. If its null I throw an exception. The problem comes in when there is an anonymous delegate that contains a function. This has a target, but is just as unremovable. The simplified code below illustrates my issues
public class MyDelegateContainer
{
List<Action<int>> m_Container = new List<Action<int>>();
public void Add(Action<int> del)
{
if (del.Target == null)
{
throw new Exception("No static handlers");
}
m_Container.Add(del);
}
public bool Remove(Action<int> del)
{
if (m_Container.Contains(del))
{
m_Container.Remove(del);
return true;
}
return false;
}
}
public class MyFakeActionClass
{
public void Test(int temp) { }
}
class Program
{
static void Main(string[] args)
{
bool removed = false;
int counter = 0;
MyDelegateContainer container = new MyDelegateContainer();
MyFakeActionClass fake = new MyFakeActionClass();
//container.Add(p => { }); //Throws, this is what I want to happen
container.Add(fake.Test); //Works, this is the use case
removed = container.Remove(fake.Test); //Works, this is the use case
Debug.Assert(removed);
container.Add(p => { fake.Test(p); counter++; }); //Works but I would like it not to
removed = container.Remove(p => { fake.Test(p); counter++; }); //doesn't work
Debug.Assert(removed);
}
}
I need some way to identify
p => { fake.Test(p); counter++; }
is an anonymous function so I can throw if someone tries it. Thanks for any help
EDIT: I should note that I could use an Action<int> variable for the anonymous function and everything would work, but the Add and Remove are never in the same scope in practice.
In your example, the caller is responsible from removing the handler. So, if the caller doesn't want to remove the handler, it won't get removed, no matter if the handler is an anonymous delegate/lambda or not.
My suggestion is to change the delegate container to something like this:
public class MyDelegateContainer
{
List<Action<int>> m_Container = new List<Action<int>>();
public Action Add(Action<int> del)
{
m_Container.Add(del);
return new Action(() =>
{
m_Container.Remove(del);
});
}
}
The caller is still responsible for removing the handler, but instead of passing the handler again to the container, it receives a "token" that it can save and use later to remove the handler.
There is no way to reliably determine whether a function is "anonymous" because all functions have names to the CLR. It's only anonymous within the language that generates it, and that's compiler-dependent. You may be able to determine the algorithm used by Microsoft's current C# compiler, only to have it stop working on C# 5 or Mono.
Since you want to prevent users of your type from writing code that uses it wrong, you just need to throw an exception at some point that will make their program crash. What I would do is throw the exception in the Remove function when the target delegate isn't found. At that point your users will still get a crash and the only way to fix it is to write the delegate in some way that it's removable.
As an added bonus, you will catch bugs where somebody tries to remove delegates twice or that were never added in the first place. The code would look like this:
public bool Remove(Action<int> del)
{
if (m_Container.Contains(del))
{
m_Container.Remove(del);
return true;
}
throw new ArgumentException("Attempt to remove nonexistent delegate");
}
I would use introspection to check the names of the methods.
Anonymous methods typically have very predictable names. (I don't remember the exact format, but run some tests, and it should be obvious).
The drawback would be that if anyone created a non-anonymous method, but decided to name it anonMethod123 (or whatever the format is...) It would be falsely rejected.
Of course you can remove an anonymous method, you just need to have a reference to the same anonymous method.
var myAnonymousMethod = p => { fake.Test(p); counter++; };
container.Add(myAnonymousMethod);
removed = container.Remove(myAnonymousMethod);
As jonnii suggested in a comment, another way you could implement it is with a dictionary:
public class MyDelegateContainer
{
Dictionary<string, Action<int>> m_Container =
new Dictionary<string, Action<int>>();
public void Add(string key, Action<int> del)
{
m_Container.Add(key, del);
}
public bool Remove(string key)
{
return m_Container.Remove(key);
}
}
Then you could easily remove a known delegate at some arbitrary point in your code just by knowing what name was used to add it:
container.Add("fake.Test", fake.Test);
removed = container.Remove("fake.Test");
Debug.Assert(removed);
container.Add("anon", p => { fake.Test(p); counter++; });
removed = container.Remove("anon"); // works!
Debug.Assert(removed);
Old question I know but I would think that this would be a current (and future) proofed way of checking if a method is anonymous:
bool isAnonymous = !System.CodeDom.Compiler.CodeGenerator.IsValidLanguageIndependentIdentifier(del.Method.Name);
The runtime name of the anonymous method would have to be invalid if used at compilation time to ensure that it didn't clash.

Categories

Resources