how to stop the execution of current method call - c#

if a condition occurs i have to stop the execution of the current method call and return to the state before the method call .how can i do it .. suppose a i am executing some sample method and a condition occurs and i am prompting a message box and then i want to return to state before this function call

If I'm understanding you correctly, you wish to undo changes you have made to certain variables if some condition is true? If that's the case, you will want to store a copy of all your variables (or your class as a whole). Then, if your condition comes up true, you'll have to revert all those variables to their initial state before returning from your function. It would be something like this:
// In order to clone your variable, you may need to inherit from
// ICloneable and implement the Clone function.
bool MyFunction(ICloneable c)
{
// 1. Create a copy of your variable
ICloneable clone = c.Clone();
// 2. Do whatever you want in here
...
// 3. Now check your condition
if (condition)
{
// Copy all the attributes back across to c from your clone
// (You'll have to write the ResetAttributes method yourself)
c.ResetAttributes(clone);
// Put a message box up
MessageBox.Show("This failed!");
// Now let the caller know that the function failed
return false;
}
else
{
// Let the caller know that the function succeeded
return true;
}
}

A generic rollback functionality on the heap is for me unheard of. But you can use the Command pattern to get undo functionality and use it for rolling back:
http://en.wikipedia.org/wiki/Command_pattern
Essentially you encapsulate an operation in an object that stores enough information of the change that it can undo it. You push that object onto a stack, and when your condition occurs, you go pop all command objects from the stack and undo them. Without more information about your case it's difficult to give more specific information or tell whether this is applicable for you.

Is it an error condition that could have been checked before calling the method? If so, throw an exception.
Otherwise, return something meaningful (e.g. if it's a void function, change it to return a bool, and return false).

This is what exceptions are for. You throw an exception to terminate the function and any caller, until an exception handler is reached.
Note that this should only be done if something exceptional has occurred; exceptions shouldn't be used as a "different kind of" return value, as they are more costly in terms of code size (whether thrown or not) and running time (if thrown) , than normals returns.
As far as returning to the state you had before, this is possible if your code and any library code through which the call proceeded was written in an exception safe manner.

I guess you are talking on the lines of object transactions OR transactional memory.
The least you can do is you can record the state (assignments) of the object being modified and write the old values on it when the condition to assignment fails.

Another solution, differing slightly from those above:
Check for the specified condition a bit now and then in your sample method.
public void MyMethod()
{
some code
if (conditionOccurred == true){ reset to the previous state and exit;}
more code
}
This is probably not according to the book, but it gives quite simple and readable code if you don't use it too often.
I probably don't have to mention that you need save the program's state if you want to be able to return to it, and you need to write some code that returns you to this state.

You can use the Memento pattern to implement object rollback. From here ...
The caretaker is going to do something
to the originator, but wants to be
able to undo the change. The caretaker
first asks the originator for a
memento object. Then it does whatever
operation (or sequence of operations)
it was going to do. To roll back to
the state before the operations, it
returns the memento object to the
originator.
Once you receive the event that indicates that you should roll back, you can undo the change and return to the caller. Here is some info. and links on why you should not use Thread.Abort.

Related

Subsequent method calls to same method enters a new context?

I have a question regarding method calls and stack pointers.
Basically I have a program that reads input from the user. After creating an object of a class "Input", a method call "prompt()" presents a menu with choices, and each choice you make calls a new method that performs some operations. After making a choice, you can always choose to go back to the main menu, and this action calls "prompt()" again.
Now, my question is, will each call of "prompt()" point to a new place in the memory stack or will it enter the same context as when the first call was made? I.e is it possible to create a memory leak by going back to the main menu over and over?
class inOut {
public string[] Prompt(){
...
presentChoices();
...
}
private void PresentChoices(){
...
if(someChoice){
manualInput();
}
...
}
private void ManualInput(){
...
if(goBack){
Prompt();
}
...
}
}
I hope the question was clear and thanks in advance for any answers on this!
For each method you enter there should be a corresponding return. Otherwise it may lead to StackOverlow. It's not a new context, but a values left in stack, which are used for return to return to the point where method was called and for method call itself (to pass parameters).
To have something repeating itself you can use infinite loop:
while(true)
{
... // repeat this action
if(endcondition)
break;
}
In your case repeated action is call to prompt() to show menu. It may have return value to tell whenever repeat or exit, which you use in endcondition.
As Long as you call the method on the same object instance, it's going to be the same pointer to the same adress.
When you create new instances of an object each object has it's own pointer.
If you want to avoid that then you need to define the method as static. In this case you will call the method not from an instance but from the type.
Something you need to be careful about especially when you call the same method over and over again from the same instance context are recursive calls. To many recursive calls (many thousands) will result in a StackOverFlowException (like the Name of this website). You can find out if you have recursive calls in the StackTrace pane in Visual Studio or if you have Resharper installed it will tell you on the left side of the document.
Either way, what you are describing here is not really a "Memory Leak" (ML's are unused objects that do not get collected and stay in memory not doing anything) but rather a stack Overflow Situation.
Objects that are not referenced anymore are garbage collected.Thats what will happen to your Input object.
Unlesss...
... you do it wrong.
In Winform applications doing it wrong usually happens when there are eventhandlers involved that for some reason (the publisher of the event lives longer than the subscriber) prevent the garbage collection.
Suppose your code looks something like this:
void Prompt()
{
// ...
var obj = new Input();
// ...
if (someCondition)
{
Prompt(); // recursive
}
// ...
// Is 'obj' used here?
}
Then when you call Prompt() recursively, yes, a new context is created. The obj variable will point to a new object, etc.
If the recursion becomes very, very deep, you might get a StackOverflowException (no more space on the stack for new "call frames"), or you might get an OutOfMemoryException (no more heap space for Input instances).
However, if you know for some reason that the recursion will not become too deep, the Garbage Collector will clean things for you when it is safe to do so.
But maybe you should consider a while (or do) loop instead of having your method call itself? It really depends on what you want to achieve.
I may have misunderstood your question. Maybe Prompt() is not called from within Prompt itself? You should give simplified structure of your code (like my code sample above) to make it clear what calls what from where.

Knowing in what part the method returned

Is it possible to get run-time information about where a method has returned?
I mean, if the method returned after running all its lines of code, or because of an earlier
return statement that occurred due to some condition.
The scenario is using interceptor for creating UnitOfWork that should exists in method scope.
For example, lets consider this code:
[UnitOfWork]
public void Foo()
{
// insert some values to the database, using repositories interfaces...
DoSomeChangesInTheDataBaseUsingRepositories();
var result = DoSomethingElse();
if (!result) return;
DoMoreLogicBecuseTheResultWasTrue();
}
I have interceptor class that opens thread static unit of work for methods that are flagged with [UnitOfWork] and when the scope of the method ends it run commit on the UoW and dispose it.
This is fine, but lets consider the scenario above, where for some reason a programmer decided to return in the middle of the method due to some condition, and in that scenario the changes made by the repositories should not be persisted.
I know that this can indicate wrong design of the method, but be aware that it is a possible scenario to be written by a programmer and I want to defend my database from these kind of scenarios.
Also, I don't want to add code to the method itself that will tell me where it ended. I want to infer by the method info somehow its returned point, and if it is not at the end of its scope the interceptor will know not to commit.
The simple answer is use BREAKPOINTS and Debugging.
Edit:- As mentioned by Mels in the comments. This could be a useful suggestion.
If your application is very timing-sensitive, set conditional breakpoints such that they never actually stop the flow of execution. They do keep track of Hit Count, which you can use to backtrace the flow of execution.
Just for your attention. From the microsoft site:-
For those out there who have experience debugging native C++ or VB6
code, you may have used a feature where function return values are
provided for you in the Autos window. Unfortunately, this
functionality does not exist for managed code. While you can work
around this issue by assigning the return values to a local variable,
this is not as convenient because it requires modifying your code. In
managed code, it’s a lot trickier to determine what the return value
of a function you’ve stepped over. We realized that we couldn’t do the
right thing consistently here and so we removed the feature rather
than give you incorrect results in the debugger. However, we want to
bring this back for you and our CLR and Debugger teams are looking at
a number potential solutions to this problem. Unfortunately this is
will not be part of Visual Studio 11.
There are a couple ways that normally indicate that a method exited early for some reason, one is to use the actual return value, if the value is a valid result that then your method probably finished correctly, if its another value then probably not, this is the pattern that most TryXXX methods follow
int i;
//returns false as wasn't able to complete
bool passed = int.TryParse("woo", out i);
the other is to catch/trhow an exception, if an exception is found, then the method did not complete as you'd expect
try
{
Method();
}
catch(Exception e)
{
//Something went wrong (e.StackTrace)
}
Note: Catching Exception is a bad idea, the correct exceptions should be caught, i.e NullReferenceException
EDIT:
In answer to your update, if your code is dependant on the success of your method you should change the return type to a boolean or otherwise, return false if unsuccessful
Generally you should use trace logs to watch you code flow if you cant debug it.
You could always do something like this:
private Tuple<int, MyClass> MyMethod()
{
if (condition)
{
return new Tuple<int, MyClass>(0,new MyClass());
}
else if(condition)
{
return new Tuple<int, MyClass>(1, new MyClass());
}
return new Tuple<int, MyClass>(2,new MyClass());
}
This way you´ll have an index of which return was returning your MyClass object. All depends on what you are trying to accomplish and why - which is at best unclear. As someone else mentioned - that is what return values are for.
I am curios to know what you are trying to do...

Error communication and recovery approaches in .NET

I am trying to do error communication and recovery in my C# code without using Exceptions.
To give an example, suppose there is a Func A, which can be called by Func B or Func C or other functions. Func A has to be designed keeping reuse in mind. (This application has an evolving library where new features will keep getting added over a period of time)
If Func A is not able to do what it is supposed to do, it returns an int, where any non-zero value indicates failure. I also want to communicate the reason for failure. The caller function can use this information in multiple ways:
It can show the error message to the user,
It may display its own error message more relevant to its context
It may itself return an int value indicating failure to further ancestor caller functions.
It may try to recover from the error, using some intelligent algorithm.
Hypothetically, any function on which other functions depend, may need to communicate multiple things to its caller function to take appropriate action, including status code, error message, and other variables indicating the state of data. Returning everything as a delimited string may not allow the caller function to retrieve the information without parsing the string (which will lead to its own problems and is not recommended).
The only other way is to return an object containing member variables for all required information. This may lead to too many 'state' objects, as each function will need to have its state object.
I want to understand how this requirement can be designed in the most elegant way. Note that at the time of coding, Func A may not know whether the caller function will have the intelligence to recover from the error or not, so I do not want to throw exceptions. Also, I want to see whether such a design is possible (and elegant at the same time) without using exceptions.
If the only way is to communicate using data objects for each function, then is it the way professional libraries are written. Can there be a generic data object? Note new functions may be added in future, which may have different state variables, or supporting information about their errors.
Also note that since the function's return value is a 'state' object, the actual data what it is supposed to return may need to be passed as a ref or out parameter.
Is there a design pattern for this?
I have read the following articles before posting this question:
http://blogs.msdn.com/b/ricom/archive/2003/12/19/44697.aspx
Do try/catch blocks hurt performance when exceptions are not thrown?
Error Handling without Exceptions
I have read many other articles also, which suggest not to use exceptions for code flow control, and for errors which are recoverable. Also, throwing exceptions have their own cost. Moreover, if the caller function wants to recover from exception thrown by each of the called functions, it will have to surround each function call with a try catch block, as a generic try catch block will not allow to 'continue' from the next line of the error line.
EDIT:
A few specific questions:
I need to write an application which will synchronize 2 different databases: one is a proprietory database, and the other is a SQL Server database. I want to encapsulate reusable functions in a separate layer.
The functionality is like this: The proprietory application can have many databases. Some information from each of these databases needs to be pushed to a single common SQL Server database. The proprietory application's databases can be read only when the application's GUI is open and it can be read only through XML.
The algorithm is like this:
Read List of Open databases in Proprietory Application
For each database, start Sync process.
Check whether the user currently logged in, in this database has the Sync Permission. (Note: each database may be opened using a different user id).
Read data from this database.
Transfer data to SQL Server
Proceed to next database.
While developing this application, I will be writing several reusable functions, like ReadUserPermission, ReadListOfDatabases, etc.
In this case, if ReadUserPermission finds that the permission does not exist, the caller should log this and proceed to next open database. If ReadListOfDatabases is not able to establish a connection with the Proprietory Application, the caller should automatically start the application, etc.
So which error conditions should be communicated should exceptions and which using return codes?
Note the reusable functions may be used in other projects, where the caller may have different error recovery requirements or capabilities, so that has to be kept in mind.
EDIT:
For all those advocating exceptions, I ask them:
If Func A calls Func B,C,D,E,F,G and Func B throws an exception on some error condition, but Func A can recover from this error and will like to continue rest of execution i.e. call Func B,C,D,..., how does exception handling allow to do this 'elegantly'? The only solution will be to wrap calls to each of B,C,D,... within a try catch block, so that remaining statements get executed.
Please also read these 2 comments:
https://stackoverflow.com/a/1279137/1113579
https://stackoverflow.com/a/1272547/1113579
Note I am not averse to using exceptions, if error recovery and remaining code execution can be achieved elegantly and without impacting performance. Also, slight performance impact is not a concern, but I prefer the design should be scalable and elegant.
EDIT:
Ok, Based on "Zdeslav Vojkovic" comments', I am now thinking about using exceptions.
If I were to use exceptions, can you give some use case when not to use exception, but use return codes? Note: I am talking about return codes, not the data which function is supposed to return. Is there any use case of using return codes to indicate success / failure, or no use case? That will help me understand better.
One use case of exceptions what I have understood from "Zdeslav Vojkovic" is when the callee function wants to compulsorily notify caller function of some condition and interrupt the caller execution. In the absence of exception, the caller may or may not choose to examine the return codes. But in case of exceptions, the caller function must necessarily handle the exception, if it wants to continue execution.
EDIT:
I had another interesting idea.
Any callee function which wants to support the idea of caller function recovering from its error can raise event, and check the event data after the event has been handled, and then decide to throw or not to throw exception. Error codes will not be used at all. Exceptions will be used for unrecovered errors. Basically when a callee function is unable to do what its contract says, it asks for "help" in the form of any available event handlers. Still if it is not able to perform the contract, it throws an exception. The advantage is that the added overhead of throwing exceptions is reduced, and exceptions are thrown only when the callee function or any of its caller functions are not able to recover from the error.
Suppose if the caller function does not want to handle the error, but rather the caller's caller function wants to handle the error, the custom event dispatcher will ensure that event handlers are called in the reverse order of event registration, i.e. the most recently registered event handler should be called prior to other registered event handlers, and if this event handler is able to resolve the error, the subsequent event handlers are not at all called. On the other hand, if the most recent event handler can not resolve the error, the event chain will propagate to the next handler.
Please give feedback on this approach.
How about a common FunctionResult object that you use as an out param on all your methods that you don't want to throw exceptions in?
public class FuncResultInfo
{
public bool ExecutionSuccess { get; set; }
public string ErrorCode { get; set; }
public ErrorEnum Error { get; set; }
public string CustomErrorMessage { get; set; }
public FuncResultInfo()
{
this.ExecutionSuccess = true;
}
public enum ErrorEnum
{
ErrorFoo,
ErrorBar,
}
}
public static class Factory
{
public static int GetNewestItemId(out FuncResultInfo funcResInfo)
{
var i = 0;
funcResInfo = new FuncResultInfo();
if (true) // whatever you are doing to decide if the function fails
{
funcResInfo.Error = FuncResultInfo.ErrorEnum.ErrorFoo;
funcResInfo.ErrorCode = "234";
funcResInfo.CustomErrorMessage = "Er mah gawds, it done blewed up!";
}
else
{
i = 5; // whatever.
}
return i;
}
}
Make sure all of your functions that can fail without exceptions have that out param for FuncResultInfo
"is it the way professional libraries are written?"
No, professional libraries are written by using exceptions for error handling - I am not sure if there is a pattern for using your suggested approach, but I consider it an anti-pattern (in .NET). After all, .NET itself is a professional framework and it uses exceptions. Besides, .NET developers are used to exceptions. Do you think that your library is really that special to force the users to learn completely different way of error handling?
What you just did is reinvent the COM error handling. If that is what you want to do then check this and ISupportErrorInfo interface for some ideas.
Why do you want to do this? I bet it is a performance 'optimization'.
Fear of performance issues with regard to exception handling is almost always a premature optimization. You will create an awkward API where each return value must be handled via ref/out parameters and which will hurt every user of your lib, just to solve the problem which likely doesn't exist at all.
"Func A may not know whether the caller function will have the
intelligence to recover from the error or not, so I do not want to
throw exceptions"
So you want to ensure that caller silently allows FuncA to mess up the system invariants and caller just goes on happily? It will just make it much harder to debug seemingly impossible bug which happens in another function later on due to this.
There are scenarios where it makes sense to avoid exceptions, but there should be a good justification for that. Exceptions are good idea.
EDIT: I see that you have added that you "have read many other articles also, which suggest not to use exceptions for code flow control". That is correct, exceptions in .NET are not for code flow but for error handling.
You ask:
If Func A calls Func B,C,D,E,F and it has to encapsulate each call
with try catch because it can recover from error or it will still like
to execute remaining function calls, then is not so many try catch
statements awkward
not more than alternative. You are making a mistake that you can simple handle all errors returned from functions in a same way but you usually can't.
Consider if you need to handle every function separately - worst case scenario and code is usually not written like that:
Result x, y;
try {
x = Function1();
}
catch(SomeException e) {
// handle error
}
try {
y = Function2();
}
catch(SomeOtherException e) {
// handle error
}
against:
int error;
Result x, y;
error = Function1(out x);
if(error != SOME_KNOWN_ISSUE) {
// handle error
}
error = Function2(out y);
if(error != SOME_KNOWN_ISSUE) {
// handle error
}
not a big difference. please don't tell me that you would not check the error code.
However, if you decide to ignore all errors (a horrible idea) then exceptions are simpler:
try {
var x = Function1();
var y = Function2();
var z = Function3();
}
catch Exception() { you still can see the message here and possibly rethrow }
vs
Result1 r1;
Function1(out r1);
Result2 r2;
Function2(out r2);
Result3 r3;
Function3(out r3);
// and here you still don't know whether there was an error
Can you elaborate what do you mean by "I need predictability with regard to time constraints"?
in some system level software or realtime stuff, you can't afford stack unwinding related to exception handling, as you can't guarantee the duration, and that could violate your timing requirements. But this is never the case in .NET as garbage collection is far worse in this regard.
Also, when you say "In .NET I would always use the exceptions for
error handling", can you explain how or what do you define as an error
condition? Is a recoverable situation an error condition or not an
error condition? –
#shambulater already gave a great example in comments. In FileStream, missing file is not recoverable and it will throw. In the client of FileStream it might be recoverable or not depending on context. Some clients will ignore it, some will exit the app, some will wrap it in another exception and let someone upstream to decide.
When will you not use exceptions?
In those cases where I would also not return an error code.
I use the FunctionResult approach extensively in ms-access and it works wonderfully. I consider it far better than error handling. For a start, each error message is application specific and is not the usually off target default error message. If the error propagates up a call list of functions, the error messages can be daisy chained together. This eventual error message looks like a call stack but is cleaner e.g. [Could not read photos from Drive F:, Could not read files, Drive not ready]. Wacko, I have just discovered that some Drives can be mounted but not ready. I could not have unit tested for that error as I didn't know that such an error could occur (means SD card reader is empty). Yet even without prior knowledge of this error, I could write an application that handled it gracefully.
My method is to call a method in a class that is written as a function that returns a boolean value. The return value is set to True in the last line of the function so if the function is exited before the last line, it is by default unsuccessful. I code, calling the function looks like if getphotos(folderID) then...do something .. Else report error. Inside the class module is a module level error variable (Str mEM) and it is read via a getter, so the class has an .em property which holds the error message. I also have a comment variable which is sometimes used like an error message, for example if the folder is empty, the code that looked for photos worked but did not return any photos. That would not be an error but it is something that I might want to communicate to the calling program. If there was an error, the user would get an error message and the calling procedure would exit. In contrast, if there was a cmt, such as 'no photos', then I might skill trying to read the photo metadata for example. How does Zdeslav Vojkovic handle subtlies like that with exceptions?
I am moving to C# hence finding this thread. I like the certainty of knowing why function calls failed (I interact with databases and filing systems all the time so I struggle to cover my projects with Unit Tests). I do agree with Zdeslav Vojkovic about using exceptions where their used is standard, but will not be be doing so in my own code. I am looking for a clean design pattern that allows me to validate parameters within the called function and to inform the caller if the parameters were not right.

When does a param that is passed by reference get updated?

Suppose I have a method like this:
public void MyCoolMethod(ref bool scannerEnabled)
{
try
{
CallDangerousMethod();
}
catch (FormatException exp)
{
try
{
//Disable scanner before validation.
scannerEnabled = false;
if (exp.Message == "FormatException")
{
MessageBox.Show(exp.Message);
}
}
finally
{
//Enable scanner after validation.
scannerEnabled = true;
}
}
And it is used like this:
MyCoolMethod(ref MyScannerEnabledVar);
The scanner can fire at any time on a separate thread. The idea is to not let it if we are handling an exception.
The question I have is, does the call to MyCoolMethod update MyScannerEnabledVar when scannerEnabled is set or does it update it when the method exits?
Note: I did not write this code, I am just trying to refactor it safely.
You can think of a ref as making an alias to a variable. It's not that the variable you pass is "passed by reference", it's that the parameter and the argument are the same variable, just with two different names. So updating one immediately updates the other, because there aren't actually two things here in the first place.
As SLaks notes, there are situations in VB that use copy-in-copy-out semantics. There are also, if I recall correctly, rare and obscure situations in which expression trees may be compiled into code that does copy-in-copy-out, but I do not recall the details.
If this code is intended to update the variable for reading on another thread, the fact that the variable is "immediately" updated is misleading. Remember, on multiple threads, reads and writes can be observed to move forwards and backwards in time with respect to each other if the reads and writes are not volatile. If the intention is to use the variable as a cross-thread communications mechanism them use an object actually designed for that purpose which is safe for that purpose. Use some sort of wait handle or mutex or whatever.
It gets updated live, as it is assigned inside the method.
When you pass a parameter by reference, the runtime passes (an equivalent to) a pointer to the field or variable that you referenced. When the method assigns to the parameter, it assigns directly to whatever the reference is pointing to.
Note, by the way, that this is not always true in VB.
Yes, it will be set when the variable is set within the method. Perhaps it would be best to return true or false whether the scanner is enabled rather than pass it in as a ref arg
The situation calls for more than a simple refactor. The code you posted will be subject to race conditions. The easy solution is to lock the unsafe method, thereby forcing threads to hop in line. The way it is, there's bound to be some bug(s) in the application due to this code, but its impossible to say what exactly they are without knowing a lot more about your requirements and implementation. I recommend you proceed with caution, a mutex/lock is an easy fix, but may have a great impact on performance. If this is a concern for you, then you all should review a better thread safe solution.

Does C# have a way to mimic Software Transactional Memory, on a small scale?

Does C# have a way to temporarily change the value of a variable in a specific scope and revert it back automatically at the end of the scope/block?
For instance (not real code):
bool UpdateOnInput = true;
using (UpdateOnInput = false)
{
//Doing my changes without notifying anyone
Console.WriteLine (UpdateOnInput) // prints false
}
//UpdateOnInput is true again.
EDIT:
The reason I want the above is because I don't want to do this:
UpdateOnInput = false
//Doing my changes without notifying anyone
Console.WriteLine (UpdateOnInput) // prints false
UpdateOnInput = true
No, there's no way to do this directly. There are a few different schools of thought on how to do this sort of thing. Compare and contrast these two:
originalState = GetState();
SetState(newState);
DoSomething();
SetState(originalState);
vs
originalState = GetState();
SetState(newState);
try
{
DoSomething();
}
finally
{
SetState(originalState);
}
Many people will tell you that the latter is "safer".
It ain't necessarily so.
The difference between the two is of course the the latter restores the state even if DoSomething() throws an exception. Is that better than keeping the state mutated in an exception scenario? What makes it better? You have an unexpected, unhandled exception reporting that something awful and unexpected has happened. Your internal state could be completely inconsistent and arbitrarily messed up; no one knows what might have been happening at the point of the exception. All we know is that DoSomething probably was trying to do something to the mutated state.
Is it really the right thing to do in the scenario where something terrible and unknown has happened to keep on stirring that particular pot and trying to mutate the state that just caused an exception again?
Sometimes that is going to be the right thing to do, and sometimes its going to make matters worse. Which scenario you're actually in depends on what exactly the code is doing, so think carefully about what the right thing to do is before just blindly choosing one or the other.
Frankly, I would rather solve the problem by not getting into the situation in the first place. Our existing compiler design uses this design pattern, and frankly, it is freakin' irritating. In the existing C# compiler the error reporting mechanism is "side effecting". That is, when part of the compiler gets an error, it calls the error reporting mechanism which then displays the error to the user.
This is a major problem for lambda binding. If you have:
void M(Func<int, int> f) {}
void M(Func<string, int> f) {}
...
M(x=>x.Length);
then the way this works is we try to bind
M((int x)=>{return x.Length;});
and
M((string x)=>{return x.Length;});
and we see which one, if any, gives us an error. In this case, the former gives an error, the latter compiles without error, so this is a legal lambda conversion and overload resolution succeeds. What do we do with the error? We cannot report it to the user because this program is error free!
Therefore what we do when we bind the body of a lambda is exactly what you say: we tell the error reporter "don't report your errors to the user; save them in this buffer over here instead". Then we bind the lambda, restore the error reporter to its earlier state, and look at the contents of the error buffer.
We could avoid this problem entirely by changing the expression analyzer so that it returned the errors along with the result, rather than making errors a state-related side effect. Then the need for mutation of the error reporting state goes away entirely and we don't even have to worry about it.
So I would encourage you to revisit your design. Is there a way you can make the operation you are performing not dependent upon the state you are mutating? If so, then do that, and then you don't need to worry about how to restore the mutated state.
(And of course in our case we do want to restore the state upon an exception. If something inside the compiler throws during lambda binding, we want to be able to report that to the user! We don't want the error reporter to stay in the "suppress reporting errors" state.)
No, but it is pretty simple to just do this:
bool UpdateOnTrue = true;
// ....
bool temp = UpdateOnTrue;
try
{
UpdateOnTrue = false;
// do stuff
}
finally
{
UpdateOnTrue = temp;
}
Try:
public void WithAssignment<T>(ref T var, T val, Action action)
{
T original = var;
var = val;
try
{
action();
}
finally
{
var = original;
}
}
Now you can say:
bool flag = false;
WithAssignment(ref flag, true, () =>
{
// flag is true during this block
});
// flag is false again
No, you have to do it manually with a try/finally block. I dare say you could write an IDisposable implementation which would do something hacky in conjunction with lambda expressions, but I suspect a try/finally block is simpler (and doesn't abuse the using statement).
Sounds like you really want
Stack<bool>
No , there is not standard way, you should implement it manually. Generic implementation of IEditableObject via TypeDescriptor and Reflection can be helpfull
Canned... I doubt it. Given your example is a simple use of a temporary bool value I'm assuming you've got something wacky in mind :-) You can implement some kind of Stack stucture:
1) Push old value onto stack
2) Load new value
3) Do Stuff
4) Pop from stack and replace used value.
Rough (AKA Untested) example (Can't look up stack syntax right now)
bool CurrentValue = true;
Stack<bool> Storage= new Stack<bool>
Storage.Push(CurrentValue);
CurrentValue=false;
DoStuff();
CurrentValue = Storage.Pop();
//Continue
You should refactor your code to use a separate function, like so:
bool b = GetSomeValue();
DoSomething(ModifyValue(b));
//b still has the original value.
For this to work for a reference type, you need to copy it before messing with it:
ICloneable obj = GetSomeValue();
DoSomething(ModifyValue(obj.Clone()));
//obj still has the original value.
It's hard to write correct code when the values of your variables change around a lot. Strive to have as few reassignments in your code as possible.

Categories