Is there a concise way to loop over true/false in C#?
I have ~20 lines of code in a unit test I'd rather not duplicate to toggle one boolean true/false.
I could break it off into a function and call it twice, but meh. This code feels more like I'm iterating over possible values than performing a distinct action with different parameters. Even if I had a function, I'd prefer the syntax of looping over the possible values rather than just calling it twice.
I could write a for loop like so...
bool toggle;
for (int i = 0; i < 2; i++)
{
toggle = i == 1;
}
But that doesn't seem very clean.
I like this syntax:
for (bool b : { false, true }) { /* ... */ }
But it doesn't look like that will compile in C#.
Edit:
Following Jeroen's suggestion about local functions and Dmitry's answer, this is the route I went:
[TestMethod]
public void GetAndSetValue()
{
foreach (bool toggle in new [] { false, true })
{
GetAndSetValue(toggle);
}
void GetAndSetValue(bool toggle)
{
// details not important
}
}
Reasonable coders can debate whether the loop reads more easily than two function calls:
GetAndSetValue(false);
GetAndSetValue(true);
I like the loop better, so I'll roll with it until someone complains. Cheers!
Correct syntax will be foreach, not for:
foreach (bool b in new [] { false, true }) {
/* ... */
}
While I think simply writing a parametrized function is definitely the correct approach, the closest to that C++11 syntax that you can get in C# would be:
foreach (bool value in new [] { false, true })
{
// ...
}
I would probably just do it this way, either with a local function:
[TestMethod]
public void GetAndSetValue()
{
GetAndSetValue(false);
void GetAndSetValue(bool toggle)
{
// details not important
if (!toggle)
GetAndSetValue(true);
}
}
Or "old" school with a private method.
[TestMethod]
public void GetAndSetValue()
{
GetAndSetValue(false);
}
private void GetAndSetValue(bool toggle)
{
// details not important
if (!toggle)
GetAndSetValue(true);
}
Related
I have been reading some C# interview questions and found a permutation of a popular one about delegates the code of which puzzles me.
The question was:
Predict the output of the code below.
delegate void Iterator();
static void Main(string[] args)
{
List<Iterator> iterators = new List<Iterator>();
for (int i = 0; i < 15; i++)
{
iterators.Add(delegate { Console.WriteLine(i); });
}
foreach (var iterator in iterators)
{
iterator();
}
Console.Read();
}
The normal version of this question I've seen declares the i variable before the for loop, thus making it method-wide and from there it's easy to see why the output is "15" 15 times.
However when I debugged the code the i variable is out of scope in the foreach loop and does not exist, anymore. Yet, when I step into the iterator() method it exists for the Console.WriteLine(i) line.
This I cannot understand.
The compiler translates your code to the following code, this is why i variable is not out of scope.
private delegate void Iterator();
[CompilerGenerated]
private sealed class CompGenCls
{
public int i;
internal void CompGenFunc()
{
Console.WriteLine(i);
}
}
private static void Main(string[] args)
{
List<Iterator> iterators = new List<Iterator>();
CompGenCls obj = new CompGenCls();
obj.i = 0;
for (; obj.i < 15; obj.i++)
{
iterators.Add(obj.CompGenFunc);
}
foreach (Iterator item in iterators)
{
item();
}
Console.Read();
}
To put it very simply, closures allow you to encapsulate some
behaviour, pass it around like any other object, and still have access
to the context in which they were first declared. This allows you to
separate out control structures, logical operators etc from the
details of how they're going to be used. The ability to access the
original context is what separates closures from normal objects,
although closure implementations typically achieve this using normal
objects and compiler trickery.
In your example you've only actually declared a single i variable -
so that same i variable is captured by all the Action instances. The
result is the number 15 being printed on every line. o "fix" the code
to make it display the output most people would expect (i.e. 0 to 14)
we need to introduce an extra variable inside the loop:
delegate void Iterator();
static void Main(string[] args)
{
List<Iterator> iterators = new List<Iterator>();
for (int i = 0; i < 15; i++)
{
int copy = i;
iterators.Add(delegate { Console.WriteLine(copy); });
}
foreach (var iterator in iterators)
{
iterator();
}
Console.Read();
}
Each time we go through the loop we're said to get a different
instance of the copy variable - each Action captures a different
variable. This makes perfect sense if you look at what the compiler's
actually doing behind the scenes, but initially it flies in the face
of the intuition of most developers (including me).
via
I am looking to pass a line of code into a function I am calling in c# with the intention to optimise my code and attempt to learn something new. I am familiar with using strings, ints, floats, booleans as I have shown in my code.
The idea is to call a function on a button click that stops a script and begins a script again. Without the function this code is working:
public void PlayOnClick()
{
if(count != 1)
{
m_animator.GetComponent<Animator>().Play("Scale");
d_animator.GetComponent<Animator>().Play("CloseUp");
((MovieTexture)MovieOne.GetComponent<Renderer>().material.mainTexture).Play();
Dialyser.GetComponent<RotationByMouseDrag>().enabled = false;
count = 1;
}
else
{
m_animator.GetComponent<Animator>().Play("Scale");
d_animator.GetComponent<Animator>().Play("ScaleDown");
((MovieTexture)MovieOne.GetComponent<Renderer>().material.mainTexture).Stop();
Dialyser.GetComponent<RotationByMouseDrag>().enabled = true;
count = 0;
}
}
However I believe this can be shortened. I have got this so far:
void Lock(string A, string B, ? C, bool D, int E)
{
m_animator.GetComponent<Animator>().Play(A);
d_animator.GetComponent<Animator>().Play(B);
C;
Dialyser.GetComponent<RotationByMouseDrag>().enabled = D;
count = E;
}
In function C I would want to pass the following line when pressed once:
((MovieTexture)MovieOne.GetComponent<Renderer>().material.mainTexture).Stop();
And have it change to this when pressed again:
((MovieTexture)MovieOne.GetComponent<Renderer>().material.mainTexture).Play();
I have come across eval - but I believe that is just for javascript and could be quite processor intensive. I have looked into parsing the line as a string.
I am currently coming up trumps on searches and on attempts. Could anyone shed some light on this for me?
What you are looking for is called delegates, or function pointers in c++ terms.
You can find more on delegates here.
Actions might feel more quicker to code with.
Basically, you can pass a reference to a method you want to execute. The signature of the method should be exactly the same as parameter type declared in the method. So if you expect to pass and run a piece of code that does not return any value, you could use Action type, without any type parameters. For example
class A {
void printAndExecute(String textToPrint, Action voidMethodToExecute) {
Debug.Log(textToPrint);
voidMethodToExecute();
}
}
class B : MonoBehaviour {
void Start() {
new A().printAndExecute("SAY", sayHello);
}
void sayHello() {
Debug.Log("Hello!");
}
}
Hope it helps
You have to pass an Action type or a custom delegate :
void Lock(string A, string B, System.Action C, bool D, int E)
{
m_animator.GetComponent<Animator>().Play(A);
d_animator.GetComponent<Animator>().Play(B);
C();
Dialyser.GetComponent<RotationByMouseDrag>().enabled = D;
count = E;
}
// ...
Lock("Scale", "CloseUp", ((MovieTexture)MovieOne.GetComponent<Renderer>().material.mainTexture).Play, false, 1 ) ;
This is a bit hard to explain, but I'm hoping this example will clear it up.
Say I have some function call Visible:
public bool Visible(/* Some page element */)
{
// Checks if something on a webpage is visible. Returns a "true" is yes, and "false" if not
}
Is it possible to some how wait for this function to return true? What I've written out so far looks like this:
public void WaitUntil(/*function returning bool*/ isTrue)
{
for (int second = 0; ; second++)
{
if (second >= 12)
{
/* Thow exception */
}
else
{
if (isTrue /*calls the isTrue function with given parameters*/)
{
return;
}
}
}
}
Such that these two method could be used together like:
WaitUntil(Visible(/* Some page element */));
to wait until a page element is visible... Is this possible?
Here is how to do it (although you should consider using events as this kind of "waiting" is strongly discouraged)
/*Important Note: This is ugly, error prone
and causes eye itchiness to veteran programmers*/
public void WaitUntil(Func<bool> func)
{
DateTime start = DateTime.Now;
while(DateTime.Now - start < TimeSpan.FromSeconds(12))
{
if (func())
{
return;
}
Thread.Sleep(100);
}
/* Thow exception */
}
//Call
WaitUntil(() => Visible(/* Some page element*/));
I've seen countless posts on how variable capture pulls in variables for the creation of the closure, however they all seem to stop short of specific details and call the whole thing "compiler magic".
I'm looking for a clear-cut explanation of:
How local variables are actually captured.
The difference (if any) between capturing value types vs. reference types.
And whether there is any boxing occurring with respect to value types.
My preference would be for an answer in terms of values and pointers (closer to the heart of what happens internally), though I will accept a clear answer involving values and references as well.
Is tricky. Will come onto it in a minute.
There's no difference - in both cases, it's the variable itself which is captured.
Nope, no boxing occurs.
It's probably easiest to demonstrate how the capturing works via an example...
Here's some code using a lambda expression which captures a single variable:
using System;
class Test
{
static void Main()
{
Action action = CreateShowAndIncrementAction();
action();
action();
}
static Action CreateShowAndIncrementAction()
{
Random rng = new Random();
int counter = rng.Next(10);
Console.WriteLine("Initial value for counter: {0}", counter);
return () =>
{
Console.WriteLine(counter);
counter++;
};
}
}
Now here's what the compiler's doing for you - except that it would use "unspeakable" names which couldn't really occur in C#.
using System;
class Test
{
static void Main()
{
Action action = CreateShowAndIncrementAction();
action();
action();
}
static Action CreateShowAndIncrementAction()
{
ActionHelper helper = new ActionHelper();
Random rng = new Random();
helper.counter = rng.Next(10);
Console.WriteLine("Initial value for counter: {0}", helper.counter);
// Converts method group to a delegate, whose target will be a
// reference to the instance of ActionHelper
return helper.DoAction;
}
class ActionHelper
{
// Just for simplicity, make it public. I don't know if the
// C# compiler really does.
public int counter;
public void DoAction()
{
Console.WriteLine(counter);
counter++;
}
}
}
If you capture variables declared in a loop, you'd end up with a new instance of ActionHelper for each iteration of the loop - so you'd effectively capture different "instances" of the variables.
It gets more complicated when you capture variables from different scopes... let me know if you really want that sort of level of detail, or you could just write some code, decompile it in Reflector and follow it through :)
Note how:
There's no boxing involved
There are no pointers involved, or any other unsafe code
EDIT: Here's an example of two delegates sharing a variable. One delegate shows the current value of counter, the other increments it:
using System;
class Program
{
static void Main(string[] args)
{
var tuple = CreateShowAndIncrementActions();
var show = tuple.Item1;
var increment = tuple.Item2;
show(); // Prints 0
show(); // Still prints 0
increment();
show(); // Now prints 1
}
static Tuple<Action, Action> CreateShowAndIncrementActions()
{
int counter = 0;
Action show = () => { Console.WriteLine(counter); };
Action increment = () => { counter++; };
return Tuple.Create(show, increment);
}
}
... and the expansion:
using System;
class Program
{
static void Main(string[] args)
{
var tuple = CreateShowAndIncrementActions();
var show = tuple.Item1;
var increment = tuple.Item2;
show(); // Prints 0
show(); // Still prints 0
increment();
show(); // Now prints 1
}
static Tuple<Action, Action> CreateShowAndIncrementActions()
{
ActionHelper helper = new ActionHelper();
helper.counter = 0;
Action show = helper.Show;
Action increment = helper.Increment;
return Tuple.Create(show, increment);
}
class ActionHelper
{
public int counter;
public void Show()
{
Console.WriteLine(counter);
}
public void Increment()
{
counter++;
}
}
}
Is there any way to stop a running loop inside another method or insert a break statement dynamically in C#?
Thanks
Edit : I want to be able to dynamically intercept the method and insert a break to stop the loop when an event gets triggered in another function.I have several instances of the class and I want to stop the loop in each instance whenever required and manage all the instances. Consider multiple instances to be in a generic list
Example :
List<myclass> objlist=new List<myclass>();
foreach(myclass obj in objlist)
{
obj.loopingfunction().BreakLoop //or something like this (assuming that the loopingfunction is already called)
}
I need this because I want to break the loop once the user stores some huge amount of data.When the user imports the data,I get a event fired. But I cannot keep checking the database from multiple instances since it screws up sqlserver.
This is in an ASP.Net application.
If the whole thing is running in a single thread, it wouldn't make any sense. If the loop is running, then nothing else is running at the same time. If you're running a loop on another thread and the controlling method on another thread, you can either abort the loop thread completely or check a flag inside the loop to decide whether or not you should break and set the flag appropriately in the controlling method.
Update: make that function return a boolean value indicating whether you should break and use it in an "if" statement:
if (myFunctionShouldBreakLoop()) break;
Another option would be to raise a CancelEventArgs during every iteration of the loop. Probably not the most efficient, but another option nonetheless:
private void SomeMethod()
{
for (int i = 0; i <= 100000; i++)
{
Console.WriteLine(i);
if (LoopIncrement != null)
{
CancelEventArgs args = new CancelEventArgs();
LoopIncrement(null, args);
if (args.Cancel)
{
break;
}
}
}
And then elsewhere:
myObj.LoopIncrement += MyHandler;
private void MyHandler(object sender, CancelEventArgs e)
{
if(someCondition)
{
e.Cancel = true;
}
}
This way you can somewhat control the loop from outside....
Have the condition in a locked property.
private Boolean BreakCondition
{
get { lock(_LockObject) { return _BreakCondition; } }
set { lock(_LockObject) { _BreakCondition = value; } }
}
private Boolean _BreakCondition = false;
private Object _LockObject = new Object();
if (this.BreakCondition)
{
break;
}
How about using iterators, and yield magic to solve the problem.
Here is an article on infinite lists that might be useful
http://www.codethinked.com/post/2009/02/04/Infinite-Lists-With-C-Yield.aspx
class Program
{
static void Main(string[] args)
{
Predicate<int> when = i => i > 100 && Console.ReadKey().KeyChar.ToString() == "0";
foreach(var i in Numbers().BreakOn(when))
{
Console.WriteLine(i);
}
Console.ReadLine();
}
private static IEnumerable<int> Numbers()
{
var i = 0;
while(true)
{
yield return i++;
}
}
}
public static class Util
{
public static IEnumerable<int> BreakOn(this IEnumerable<int> sequence, Predicate<int> when)
{
foreach(int i in sequence)
{
if(when(i))
{
yield break;
}
yield return i;
}
}
}
I think you can use flag
bool stop = false;
for(int i=0;i<num;i++)
{
if(stop) break;
}
The short answer is: no. If you don't control the code, then you can't cause the loop to terminate.
If you do control the code, you could build in some sort of cooperation, but it sounds messy. Maybe you can elaborate on why?