I am working with an API that uses functions that use out parameters. I want to use the value in one of these out parameters in a while loop. For example:
static int counter = 0;
static void getCounterValue(out int val)
{
val = counter;
counter++;
}
static void Main()
{
// Right now, I'm having to do this:
int checkVal = 0; // I have to figure out an appropriate starting value.
while (checkVal < 10)
{
getCounterValue(out checkVal);
Console.WriteLine("Still waiting.");
}
Console.WriteLine("Done.");
}
Is there a simpler syntax to do this? I want something more classic like while (getCounterValue() < 10), but I have to deal with the out parameters because it's an API that I can't change.
You can't do anything directly, the return value of the method call is what while will use and that can't be the value you want. If this is causing you problems, you can always wrap the method call:
int wrappedGetCounterValue()
{
int i;
getCounterValue(out i);
return i;
}
Or with C# 7:
int wrappedGetCounterValue()
{
getCounterValue(out int i);
return i;
}
And use that in your while loop.
while (wrappedGetCounterValue() < 10)
....
do
{
getCounterValue(out checkVal);
Console.WriteLine("Still waiting.");
} while (checkVal < 10)
You can use the infinite loop with break condition:
while (true)
{
int checkVal;
getCounterValue(out checkVal);
if (10 <= checkVal)
break;
Console.WriteLine("Still waiting.");
}
Note the difference between do..while (checkVal < 10) option is that you will not output "Still waiting" message if first counter value will be greater or equal to 10. You cannot do that with do..while loop unless you will duplicate loop break condition (checkVal < 10).
Another option (but with the cost of code duplication) is to use for loop:
int checkVal;
for (getCounterValue(out checkVal); checkVal < 10; getCounterValue(out checkVal))
{
Console.WriteLine("Still waiting.");
}
Console.WriteLine("Done.");
If you want to completely hide the out functionality you must use a wrapper method. If you care only for "valid" values and the validity is well-defined by the <10 expression, then you can hide the <10 expression in that wrapper, and use a Nullable<int> in your code. That would be semantically correct.
static int counter = 0;
static void getCounterValue(out int val)
{
val = counter;
counter++;
}
static Nullable<int> getValidCounterValue()
{
int outResult;
getCounterValue(out outResult);
if (outResult < 10)
{
return null;
}
else
{
return outResult;
}
}
static void Main()
{
Nullable<int> checkVal = new Nullable<int>();
while (!checkVal.HasValue)
{
checkVal = getValidCounterValue();
Console.WriteLine("Still waiting.");
}
Console.WriteLine("Done. Valid value is:" + checkVal.Value.ToString());
}
Related
I am using recursion to add two numbers together, By adding 1 to the first input one at a time until I have reached the value of the second.
Why does this work...
private static int AddMethod(int input1, int input2)
{
if (input2 == 0)
{
Console.WriteLine(input1);
return (input1);
}
else
{
input1++;
input2--;
return AddMethod(input1, input2);
}
}
But not this..
private static int AddMethod(int input1, int input2)
{
if (input2 == 0)
{
Console.WriteLine(input1);
return (input1);
}
else
{
return AddMethod(input1++, input2--);
}
}
I am using Visual Studio 2010 and .Net 4.0
Because return AddMethod(input1++, input2--); first passes your inputs, and THEN increments and decrements.
Try
return AddMethod(++input1, --input2);
Post fix increment works by first "assigning" the value, then incrementing the value.
Compare:
int a = 1;
int b = 1;
int x = a++;
int y = ++b;
So in your case, the value you pass to AddMethod is the unchanged value, it modifies the value of input1 and input2 after they are passed.
Because the ++ and -- operators are executed after passing the values as parameters to the function.
Your code:
return AddMethod(input1++, input2--);
Is equal to:
int result AddMethod(input1, input2);
input1++;
input2--;
return result;
Instead of all this, you could use:
return AddMethod(++input1, --input2);
string popIt(System.Collections.ArrayList pool,ref int spin) //"EMPTY"/str;++/"OVER"
{
if (pool.Count == 0)
{ return "EMPTY"; }
else
{
if (spin < pool.Count) { spin += 1; return pool[spin - 1].ToString(); }
else { return "OVER"; }
}
}
popIt(pools[0], spiners[0]);
This won't increment int spiners[0] in ArrayList spinners, it will only increment spin in the method, like VB.NET ByVal. I tried using ref keyword, but I get few errors, how to do this?
So you can do like this:
int spin=spiners[0];
popIt(pools[0], ref spin);
spiners[0]=spin;
Thats will work, if I correctly understand what you need.
If I call methodA and then methodB output is: "121234". But I need output: "1234", "12" from methodA and "34" from methodB. I need to remember where getNumber ended with the return, and the next call continue from here. It is possible?
MethodA snipset
int x = 0;
foreach (var num in GetNumber())
{
if (x == 2)
{
break;
}
x++;
Console.Write(num);
}
MethodB snipset
int x = 0;
foreach (var num in GetNumber())
{
if (x == 4)
{
break;
}
x++;
Console.Write(num);
}
GetNumber
static IEnumerable<int> GetNumber()
{
int x = 0;
while (true)
{
yield return x++;
}
}
You can initialize x outside the method:
static class InfiniteContinuingSequence
{
static int x = 0;
public static IEnumerable<int> GetNumbers()
{
while (true)
{
yield return x++;
}
}
}
But you will have to explicitly be careful when and where this sequence gets enumerated. If it is inadvertently enumerated multiple times, you will "lose" numbers in the sequence; if you try to exhaustively enumerate GetNumbers() you'll get either an infinite loop or an overflow; and if you try to call this from multiple threads without locking, you'll get potentially odd behavior.
Instead, I might suggest to either use an explicit enumerator, or be able to specify a "restart point" to your method (in this case at least you will not get odd behavior by multiple enumerations):
static IEnumerable<int> GetNumbers(int startingPoint = 0)
{
int x = startingPoint;
while (true)
{
yield return x++;
}
}
Change GetNumber to
static int x = 0;
static IEnumberable<int> GetNumber()
{
while (true) { yield return x++; }
}
The issue is that you have two enumerations of GetNumber. By making x static you will get the results you want. But beware this is not thread safe code.
private void button1_Click(object sender, EventArgs e)
{
String UserNumber = this.textBox1.Text;
int NewUserNumber = Convert.ToInt32(UserNumber);
int result = 0;
int second = 0;
while (NewUserNumber >= 1)
{
result = NewUserNumber * (NewUserNumber - 1);
NewUserNumber--;
}
String i = Convert.ToString(result);
this.textBox2.Text = i;
}
}
While I understand this is homework for me, I am stuck. I really really don't want this solved, I want to do it myself.
I don't understand why it's not working.. It's outputting 2 no matter what I put in.
I could do this in Java easily but the converting gets to me..
Any help would be great.
Your problem is not in the conversion. Please look at
result = NewUserNumber * (NewUserNumber - 1);
while (NewUserNumber > 1)
{
result = result * NewUserNumber;
NewUserNumber--;
}
Initialize result as
int Result=1;
And write for loop as follows
while (NewUserNumber >= 1)
{
result = result * NewUserNumber;
NewUserNumber--;
}
OR
you can even use follwing
public int Factorial(int num)
{
if(num==1)
return 1;
return num * Factorial(num-1);
}
You need to look at your while loop structure and how you are setting the result value outside it and the multiplication
while (NewUserNumber >= 1)
{
result = NewUserNumber * (NewUserNumber - 1);
NewUserNumber--;
}
String i = Convert.ToString(result);
Also you have declared another int second = 0; - dont see why you are declaring that.
My advice is to try running over the code manually with different inputs.
You should run over the loop and try to figure what is the value of result and NewUserNumber is in each iteration.
Good luck...
You should try to run a debugger on your code then step through using the watch window. This is easy to do and will show you exactly what each value is at each point (you set break points). What IDE are you using?
int Factorial(int input)
{
int answer = 0;
if (input > 0)
{
count = 1;
while (count <= input)
{
if (count == 1)
{
answer= 1;
count++;
}
else
{
answer = count * answer;
count++;
}
}
}
else
{
MessageBox.Show("Please enter only a positive integer.");
}
return answer;
}
static void Main(string[] args)
{
int number, fact;
Console.WriteLine("enter the number for geting factorial");
number = Convert.ToInt32(Console.ReadLine());
fact = number;
for (int i = fact - 1; i > 0; i--)
{
fact = fact * i;
}
Console.WriteLine(fact);
Console.ReadLine();
}
I am facing a problem in creating a console application in Visual Studio c# 2005
I created the following program in which a method (to sum 2 predefined values) is called in the program
here is the code of it
class program
{
static void Main()
{
program a;
a = new program();
Console.WriteLine(a.am1(1,2));
Console.ReadLine();
}
int sum;
public int am1(int num1, int num2)
{
sum = num1 + num2;
return sum;
}
}
Now here is the main problem I am facing, well in this program two integers (num1 and num2) are predefined, I wanted those 2 numbers to be taken from user, means user input the two numbers and then the same program goes on like above. How it should be done?
P.S remember everything should be done in methods
i hope i got your requirements ... if not, please elaborate!
public sealed class Program
{
private readonly int _number1;
private readonly int _number2;
public Program(int number1, int number2)
{
this._number1 = number1;
this._number2 = number2;
}
public int Sum()
{
return this._number1 + this._number2;
}
public static void Main(string[] args)
{
// this one here is really brutal, but you can adapt it
int number1 = int.Parse(args[0]);
int number2 = int.Parse(args[1]);
Program program = new Program(number1, number2);
int sum = program.Sum();
Console.WriteLine(sum);
Console.ReadLine();
}
}
sry, this is not my main coding style ... pfuh ... really ugly!
edit:
don't give blind trust in int.Parse(). the params are coming from the user, you better double check them!
you better triple check them, as you are doing a sum ... thankfully c# compiles with unchecked - this code may fail with an OverflowException if compiled in vb - remember ranges of int
why do you want to do a simple addition in an extra class?
you should elaborate your style (regarding your comment): separate ui-code from business-layer code!
you do not need to create an instance variable for each task - you can do that with scope variables too...!
...
Use console application command line arguments. If it suites you. Below is an example from MSDN.
public class Functions
{
public static long Factorial(int n)
{
// Test for invalid input
if ((n < 0) || (n > 20))
{
return -1;
}
// Calculate the factorial iteratively rather than recursively:
long tempResult = 1;
for (int i = 1; i <= n; i++)
{
tempResult *= i;
}
return tempResult;
}
}
class MainClass
{
static int Main(string[] args)
{
// Test if input arguments were supplied:
if (args.Length == 0)
{
System.Console.WriteLine("Please enter a numeric argument.");
System.Console.WriteLine("Usage: Factorial <num>");
return 1;
}
// Try to convert the input arguments to numbers. This will throw
// an exception if the argument is not a number.
// num = int.Parse(args[0]);
int num;
bool test = int.TryParse(args[0], out num);
if (test == false)
{
System.Console.WriteLine("Please enter a numeric argument.");
System.Console.WriteLine("Usage: Factorial <num>");
return 1;
}
// Calculate factorial.
long result = Functions.Factorial(num);
// Print result.
if (result == -1)
System.Console.WriteLine("Input must be >= 0 and <= 20.");
else
System.Console.WriteLine("The Factorial of {0} is {1}.", num, result);
return 0;
}
}
// If 3 is entered on command line, the
// output reads: The factorial of 3 is 6.